HDU_1052 Tian Ji -- The Horse Racing

版权所有,欢迎转载,转载请注明出处,谢谢微笑


Tian Ji -- The Horse Racing

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 18865    Accepted Submission(s): 5511


Problem Description
Here is a famous story in Chinese history.

"That was about 2300 years ago. General Tian Ji was a high official in the country Qi. He likes to play horse racing with the king and others."

"Both of Tian and the king have three horses in different classes, namely, regular, plus, and super. The rule is to have three rounds in a match; each of the horses must be used in one round. The winner of a single round takes two hundred silver dollars from the loser."

"Being the most powerful man in the country, the king has so nice horses that in each class his horse is better than Tian's. As a result, each time the king takes six hundred silver dollars from Tian."

"Tian Ji was not happy about that, until he met Sun Bin, one of the most famous generals in Chinese history. Using a little trick due to Sun, Tian Ji brought home two hundred silver dollars and such a grace in the next match."

"It was a rather simple trick. Using his regular class horse race against the super class from the king, they will certainly lose that round. But then his plus beat the king's regular, and his super beat the king's plus. What a simple trick. And how do you think of Tian Ji, the high ranked official in China?"

HDU_1052 Tian Ji -- The Horse Racing_第1张图片

Were Tian Ji lives in nowadays, he will certainly laugh at himself. Even more, were he sitting in the ACM contest right now, he may discover that the horse racing problem can be simply viewed as finding the maximum matching in a bipartite graph. Draw Tian's horses on one side, and the king's horses on the other. Whenever one of Tian's horses can beat one from the king, we draw an edge between them, meaning we wish to establish this pair. Then, the problem of winning as many rounds as possible is just to find the maximum matching in this graph. If there are ties, the problem becomes more complicated, he needs to assign weights 0, 1, or -1 to all the possible edges, and find a maximum weighted perfect matching...

However, the horse racing problem is a very special case of bipartite matching. The graph is decided by the speed of the horses --- a vertex of higher speed always beat a vertex of lower speed. In this case, the weighted bipartite matching algorithm is a too advanced tool to deal with the problem.

In this problem, you are asked to write a program to solve this special case of matching problem.
 

Input
The input consists of up to 50 test cases. Each case starts with a positive integer n (n <= 1000) on the first line, which is the number of horses on each side. The next n integers on the second line are the speeds of Tian’s horses. Then the next n integers on the third line are the speeds of the king’s horses. The input ends with a line that has a single 0 after the last test case.
 

Output
For each input case, output a line containing a single number, which is the maximum money Tian Ji will get, in silver dollars.
 

Sample Input
   
   
   
   
3 92 83 71 95 87 74 2 20 20 20 20 2 20 19 22 18 0
 

Sample Output
   
   
   
   
200 0 0

/*解题思路1:清晰一点(本代码使用的解题思路1)
解题思路1:这题有多种解体思路,DP,二分图最大匹配算法等,这里给出的是比较容易理解的贪心算法,具体思路如下:

先将田忌跟齐王的马的速度数组进行一次冒泡排序:
1、如果田忌最快的马比齐王最快的马快,则比之

2、如果田忌最快的马比齐王最快的马慢,则用田最慢的马跟齐最快的马比  //这是贪心的第一步

3、如果田忌最快的马的速度与齐威王最快的马速度相等
3.1、如果田忌最慢的比齐威王最慢的快,则比之                         //这是贪心的第二步
3.2、如果田忌最慢的比齐威王最慢的慢,那么用田忌最慢的马输给国王最快的马
3.3、如果田忌最慢的与齐威王最慢的一样,则考虑情况                   //这是贪心的第三步
3.3.1、如果田忌最慢的比齐威王最快的慢,则用田忌慢VS齐王快
3.3.2、否则,则田忌慢马 == 齐王快马
*/


/*
解题思路2:自己开始贪心的策略是先用田忌的快马与齐王的快马相比,>则胜一场,<则用田忌的慢马与齐王的快马相比。
=的话这里需要考虑好情况,下面是核心思路: 
思路是每次先让慢马相比,如果>胜一场,<则拉下水,=要看自己的快马能不能赢,不能赢,则拉下水,能赢则赢一场。

1.若田忌最慢的马可以战胜齐王最慢的马,那么就让它战胜那匹慢马,胜利场次加1。(田忌最慢马 > 齐王最慢马)
2.若田忌最慢的马不能战胜齐王最慢的马,那么它更加不能战胜其他的马,那就让它输,而且输给齐王最快马,失败场
次加1。(田忌最慢马 < 齐王最快马)
3.若田忌最慢的马与齐王最慢的马速度相等。此时,不能简单地认为与它打成平手就是最好情况,相反,打平是下下策,
为什么呢?
因为自己后面的队友很有可能战胜此时对方的这匹慢马,所以就算自己输一场,队友也能帮忙赢回一场,而胜一场,
输一场的收益和打平一场的收益是一样的,而且自己输的时候可以拉对方最快的马下水,给己方最快的马创造更大的
胜利机会(因为它失去了一个强劲的对手),也就是说己方最快的马很可能因为自己的牺牲再胜利一场,从这个角度看
,还是自己故意输掉比较好。
 
但是,还有一点需要注意,当自己放水前,如果己方最快的马原本就比对方最快的马快,然后还输给对方最快的马,
那么己方最快的马的才华就浪费了,为什么?
很简单,它原本就能赢,需要你放水么?- -!换句话说,这种情况下,自己的牺牲没有一点价值。
所以,在放水时,一定要保证己方最快马不快于对方最快马。满足此条件后,让己方最慢马与对方最快马去比赛
(有可能平局),这样,田忌的马就得到了充分的利用。
*/




#include<iostream>
#include<algorithm>
#include<string>
using namespace std;


void quickSort(int s[], int l, int r) //把 s[j]<=x 和 s[i]>x ,修改则可实现顺序和倒叙
{
	if(l<r)
	{
		int i=l, j=r, x=s[l];
		while(i<j)
		{
			while(i<j && s[j]<=x) // 从右向左找第一个大于x的数 
				j--;
			if(i<j)
			{
				s[i] = s[j];
				i++;
			}
			while(i<j && s[i]>x) // 从左向右找第一个小于等于x的数
				i++;
			if(i<j)
			{
				s[j]=s[i];
				j--;
			}
		}
		s[i] = x;
		quickSort(s , l , i-1); //对左分区快速排序
		quickSort(s , i+1 , r); //对右分区快速排序
	}
}


int main()
{
	int t=50,n,len1,len2,a[1000],b[1000];
	while(t--)
	{
		cin>>n;
		if(n == 0)
			return 0;
		else
		{
			for(int k=0; k<n; k++)
			{
				cin>>a[k];
			}
			for(int k=0; k<n; k++)
			{
				cin>>b[k];
			}
		}
		quickSort(a , 0 , n-1);  //快速排序
		quickSort(b , 0 , n-1);


		int i=0,j=0,s=0,sum=0;
		len1 = len2 = n-1; //最慢的马的位置


		while((i<=len1) && (j<=len2))
		{
			if(a[i] > b[j]) //田忌快马 > 齐王快马
			{
				i++; //则由田忌快马 vs 齐王快马
				j++;
				s++;
			}
			else if(a[i] < b[j]) //田忌快马 < 齐王快马
			{
				len1--; //则由田忌慢马 vs 齐王快马
				j++;
				s--;
			}
			else //田忌快马==齐王快马
			{
				if(a[len1] > b[len2]) //田忌慢马>齐王慢马
				{
					len1--; //则由田忌慢马 vs 齐王慢马
					len2--;
					s++;
				}
				else if(a[len1] < b[len2]) //田忌慢马<齐王慢马
				{
					len1--; //则由田忌慢马 vs 齐王快马
					j++;
					s--;
				}
				else //田忌慢马 == 齐王慢马
				{
					if(a[len1] < b[j]) //田忌慢马 < 齐王快马
					{
						len1--;
						j++;
						s--;
					}
					else //田忌慢马 == 齐王快马
					{
						len1--;
						j++;
					}
				}
			}
		}
		sum = s * 200;
		cout<<sum<<endl;
	}
	return 0;
}


你可能感兴趣的:(Algorithm,算法,快速排序,ACM)