df

hdu 1052 Tian Ji -- The Horse Racing

 (2011-08-26 08:32:51)
標籤: 

雜談

分類: acm雜談

Tian Ji -- The Horse Racing

Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other)
Total Submission(s) : 3   Accepted Submission(s) : 1

Font: Times New Roman | Verdana | Georgia

Font Size:  

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 <wbr>1052 <wbr>Tian <wbr>Ji <wbr>-- <wbr>The <wbr>Horse <wbr>Racing

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
開始我自己做了幾下,WA,後發現等於的情況時沒考慮,哎,開始以爲這題目簡單,原來不是我想的
那樣簡單,後看如別人的寫的思路和證明才模擬寫的,現在吧別人的給大家看下(轉載臭臭吧):

題目大意:田忌和國王賽馬,給出馬的數量n,然後是田忌的n匹馬,國王的n匹馬。問田忌最多可以贏得多少比賽(一場200塊)。

這道題目以前看過,但是沒有弄出來,思路是:田忌的最快的馬比國王最快的馬快,就用田忌最快的馬跟國王最快的馬比;如果田忌最快的馬比國王最快的馬慢,就用田忌最慢的馬比。

因爲只是知道要這樣,但對於其他的情況,根本弄不明白要怎麼比法,當馬的速度一樣快的時候,就

hdu <wbr>1052 <wbr>Tian <wbr>Ji <wbr>-- <wbr>The <wbr>Horse <wbr>Racing hdu <wbr>1052 <wbr>Tian <wbr>Ji <wbr>-- <wbr>The <wbr>Horse <wbr>Racing hdu <wbr>1052 <wbr>Tian <wbr>Ji <wbr>-- <wbr>The <wbr>Horse <wbr>Racing hdu <wbr>1052 <wbr>Tian <wbr>Ji <wbr>-- <wbr>The <wbr>Horse <wbr>Racing hdu <wbr>1052 <wbr>Tian <wbr>Ji <wbr>-- <wbr>The <wbr>Horse <wbr>Racing

因爲比賽的時候,是國王先出馬,然後田忌再出,田忌有主動權上的優勢。

先對田忌和國王的馬進行排序。

貪心的策略:

一、當田忌最快的馬比國王最快的馬快時,用田忌最快的馬贏國王最快的馬。
二、當田忌最快的馬比國王最快的馬慢時,用田忌最慢的馬輸給國王最快的馬。
三、當田忌最快的馬跟國王最快的馬一樣快時,分情況。

證明一、:假設現在國王最快的馬是K,田忌最快的馬是T,如果存在一種更優的比賽策略,讓T的對手不是K,而使得田忌贏更多的錢的話,那麼設此時K的對手是t,T的對手是k:( T>K &&T>t && K>k)
1、 若t>K,則有T>k,t>K。這個結果和T>K,t>k是相同的。
2、 若k<t≤K,則有T>k,t≤K。這個結果不如T>K,t>k來得優秀。
3、 若t≤k≤K,則有T>k,t≤K。這個結果和T>K,t≤k是相同的。
由此可知,交換各自對手後,一定不會使得結果變劣,那麼假設是不成立的。

得證!!hdu <wbr>1052 <wbr>Tian <wbr>Ji <wbr>-- <wbr>The <wbr>Horse <wbr>Racing

證明二、:因爲田忌最快的馬比國王最快的馬慢,所以田忌所有的馬都比國王最快的馬慢,也就是說此時田忌的所有馬都贏不了國王的馬,而出於貪心的思想,應該保留相比之下更快的馬,因此用最慢的馬去輸一定不會比用別的馬去輸來得劣。

得證!!hdu <wbr>1052 <wbr>Tian <wbr>Ji <wbr>-- <wbr>The <wbr>Horse <wbr>Racing

其實上面這兩個很容易就想得到,最難的是相等的時候。因爲不可以直接讓田忌最快的馬跟國王最快的馬打平,或者直接用最慢的馬去輸給國王最快的馬。(存在反例)

1、如果選擇全部打平,那麼對於田忌 1 2 3 4,國王 1 2 3 4 ,這組數據,田忌什麼黃金也得不到。但是如果選擇 1->4, 4->3, 3->2, 2->1田忌可以得到400兩黃金。 (大雄想的)

2、如果選擇用最慢的馬輸掉比賽的話,對於田忌    3 4,國王 1    4 ,這組數據,田忌一勝一負,什麼黃金也得不到,但是如果田忌選擇 3->1 , 4->4 ,一勝一平,田忌可以得到200兩黃金。

所以:對於情況三,我們應該從最慢的馬開始考慮了

1、當田忌最慢的馬比國王最慢的馬快,那麼用田忌最慢的馬贏國王最慢的馬

2、當田忌最慢的馬比國王最慢的馬慢,那麼用田忌最慢的馬輸給國王最快的馬

3、當田忌最慢的馬跟國王最慢的馬相等的時候,用田忌最慢的馬跟國王最快的馬比

證明1、:假設現在國王最慢的馬是K,田忌最慢的馬是T,如果存在一種更優的比賽策略,讓T的對手不是K,而使得田忌贏更多的錢的話,那麼設此時K的對手是t,T的對手是k:( T>K &&t>T && k>K)
1、 若T>k,則有T>k,t>K。這個結果和T>K,t>k是相同的。
2、 若T<k≤t,則有T<k,t>K。。這個結果不如T>K,t>k來得優秀。
3、 若K≤t≤k,則有T>k,t≤K。這個結果和T>K,t≤k是相同的.

由此可知,交換各自對手後,一定不會使得結果變劣,那麼假設是不成立的。

得證!!hdu <wbr>1052 <wbr>Tian <wbr>Ji <wbr>-- <wbr>The <wbr>Horse <wbr>Racing

證明2、:因爲田忌最慢的馬比國王最慢的馬慢,所以田忌最慢的馬都比國王所有的馬慢,也就是說此時田忌最慢的馬贏不了國王的任何一匹馬,而出於貪心的思想,應該去掉國王最快的馬,因此輸給國王最快的馬一定不會比輸給其他的馬來得劣。

得證!!hdu <wbr>1052 <wbr>Tian <wbr>Ji <wbr>-- <wbr>The <wbr>Horse <wbr>Racing

證明3、:因爲田忌最快T和最慢t的馬與國王最快K和最慢k的馬都相等,如果用最快的馬跟國王最快的馬比,最慢的馬和國王最慢的馬比,那麼田忌什麼收穫也沒有。此時是T->K, t->k,其實這個時候我們可以換個角度想,上面這種情況跟T->k, t->k,沒有什麼區別,都是雙方少了最快和最慢的馬。但是從證明二可知,我們必須讓最慢的馬輸給國王最快的馬,而在田忌的馬中找任何一匹比最慢的馬快一點的馬去贏國王最慢的馬都行,這樣田忌在同樣一勝一負的情況下,保留了跑得更快的馬,會比把最快的馬拿去比賽來得更優些。

得證!!hdu <wbr>1052 <wbr>Tian <wbr>Ji <wbr>-- <wbr>The <wbr>Horse <wbr>Racing

 
代碼:
#include<iostream>
#include<algorithm>
using namespace std;
#define N 1010
int T[N],K[N];
bool cmp(int a,int b)
{
       return a>b;
}
int main()
{
       int ti,tj,ki,kj,win,n;
       while(scanf("%d",&n)&&n!=0)
      {
             for(int i=0;i<n;i++)
             scanf("%d",&T[i]);
             for(i=0;i<n;i++)
             scanf("%d",&K[i]);
             sort(T,T+n,cmp);
             sort(K,K+n,cmp);
             ti=ki=0;
             tj=kj=n-1;
             for(i=0,win=0;i<n;i++)
             {
                   if(T[ti]>K[ki])
                   {
                         ti++;
                         ki++;
                         win++;
                   }
                  else if(T[ti]<T[ki])
                  {
                        tj--;
                        ki++;
                      
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章