HDU 1052 Tian Ji -- The Horse Racing【貪心在動態規劃中的運用】

來源:互聯網
上載者:User

標籤:

演算法分析:

這個問題很顯然可以轉化成一個二分圖首選的問題。把田忌的馬放左邊,把齊王的馬放右邊。田忌的馬A和齊王的B之間,如果田忌的馬勝,則連一條權為200的邊;如果平局,則連一條權為0的邊;如果輸,則連一條權為-200的邊。 然而我們知道,二分圖的首選演算法的複雜度很高,無法滿足N=2000的要求。 我們不妨用貪心思想來分析一下問題。因為田忌掌握有比賽的“主動權”,他總是根據齊王所出的馬來分配自己的馬,所以這裡不妨認為齊王的出馬順序是按馬的速度從高到低出的。由這樣的假設,我們歸納出如下貪心策略:

? 1、如果田忌剩下的馬中最強的馬都贏不了齊王剩下的最強的馬,那麼應該用最差的一匹馬去輸給齊王最強的馬。 ? 2、如果田忌剩下的馬中最強的馬可以贏齊王剩下的最強的馬,那就用這匹馬去贏齊王剩下的最強的馬。  ? 3、如果田忌剩下的馬中最強的馬和齊王剩下的最強的馬打平的話,可以選擇打平或者用最差的馬輸掉比賽。

第一個貪心策略的證明: 此時田忌的所有馬都贏不了齊王的馬,所以無論用最慢馬去輸還是用最快的馬去輸都同樣是輸,而處於貪心的思想,我們應該保留相比之下更強的馬,因此用最慢的馬去輸一定不會比用別的馬去輸來得劣,所以這是最優策略。 證畢。

第二個貪心策略的證明: 假設現在齊王剩下的最強的馬是A,田忌剩下的最強的馬是B,如果存在一種更優的比賽策略,讓B的對手不是A,而使得田忌贏更多的錢的話,那麼設此時A的對手是b,B的對手是a: 1、 若b>A,則有B>a,b>A。這個結果和B>A,b>a是相同的。 2、 若a<b≤A,則有B>a,b≤A。這個結果不如B>A,b>a來得優秀。 3、 若b≤a≤A,則有B>a,b≤A。這個結果和B>A,b≤a是相同的。 由此可知,交換各自對手後,一定不會使得結果變劣,那麼假設是不成立的。 證畢。

第三個貪心策略的證明: 因為田忌最快的馬也只是和齊王的馬打平,那麼田忌只能選擇平或輸,選擇平的話,當然只能用最快的馬去平了;選擇輸的話當時是用最慢的馬去輸來得值得,這和第一個貪心策略的思路是一樣的。 證畢。

我們發現,第三個貪心策略出現了一個分支:打平或輸掉。如果窮舉所有的情況,演算法的複雜度將比求二分圖首選還要高;如果一概而論的選擇讓最強的馬去打平比賽或者是讓最差的馬去輸掉比賽,則存在反例: ? 光是打平的話,如果齊王馬的速度分別是1 2 3,田忌馬的速度也是1 2 3,每次選擇打平的話,田忌一分錢也得不到,而如果選擇先用速度為1的馬輸給速度為3的馬的話,可以贏得200兩黃金。 ? 光是輸掉的話,如果齊王馬的速度分別是1 3,田忌馬的速度分別是2 3,田忌一勝一負,仍然一分錢也拿不到。而如果先用速度為3的馬去打平的話,可以贏得200兩黃金。

雖然因為第三個貪心出現了分支,我們不能直接的按照這種方法來設計出一個完全貪心的方法,但是通過上述的三種貪心策略,我們可以發現,如果齊王的馬是按速度排序之後,從高到低被派出的話,田忌一定是將他馬按速度排序之後,從兩頭取馬去和齊王的馬比賽。有了這個資訊之後,動態規劃的模型也就出來了! 設f[i,j]表示齊王按從強到弱的順序出馬和闐忌進行了i場比賽之後,從“頭”取了j匹較強的馬,從“尾”取了i-j匹較弱的馬,所能夠得到的最大盈利。 狀態轉移方程如下:  f[i][j]=max(f[i-1][j]+g[n-(i-j)+1][i],f[i-1][j-1]+g[j][i]);   其中g[i,j]表示田忌的馬和齊王的馬分別按照由強到弱的順序排序之後,田忌的第i匹馬和齊王的第j匹馬賽跑所能取得的盈利,勝為200,輸為-200,平為0。 本題小結: 雖然本題存在直接貪心的方法,不過它可以作為一個例子告訴大家,合理的運用貪心策略,分析出問題的一些本質之後,一些看似不能用動態規劃做的題目便可以巧妙的確立出狀態,繼而可以用動態規劃來求解。

補充:對於狀態轉移方程

 f[i][j]=max(f[i-1][j]+g[n-(i-j)+1][i],f[i-1][j-1]+g[j][i]);

還應該有兩種特殊一點的情況

1 進行到第i場比賽的時候,從頭取了0匹馬,那麼所有的馬均為從尾取的, 則f[i][j]=f[i-1][j]+g[n-(i-j)+1][i];

其中n-(i-j)+1表示從尾取的第(i-j)匹馬在整個排好順序的馬中是第幾匹馬

例如 共有8匹馬, 進行到第4場比賽的時候,從頭取了0匹馬,表示要從尾取4匹馬

1 2 3 4   5 6 7 8

即要取編號為5的這匹馬,5=8-(4-0)+1; 那麼f[4][0]=f[3][0]+g[8-(4-0)+1][4]

2 進行到第i場比賽的時候,從頭取了i匹馬,表明一直都是從頭取的馬 f[i][j]=f[i-1][j-1]+g[j][i];

Tian Ji -- The Horse Racing

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

Problem DescriptionHere 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?"

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. InputThe 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. OutputFor each input case, output a line containing a single number, which is the maximum money Tian Ji will get, in silver dollars. Sample Input392 83 7195 87 74220 2020 20220 1922 180 Sample Output20000 

 

#include<stdio.h>#include<string.h>int tian[1005],king[1005],g[1005][1005],f[1005][1005];void bubblesort(int a[],int n){int i,j,t;for(i=1;i<=n;i++){for(j=i+1;j<=n;j++){if(a[i]<a[j]){t=a[i];a[i]=a[j];a[j]=t;}}}}int max(int a,int b){if(a>b)return a;elsereturn b;}int main(){int n,i,j,maxx;while(scanf("%d",&n)!=EOF&&n) //輸入為0的 時候結束輸入 {for(i=1;i<=n;i++)scanf("%d",&tian[i]);for(i=1;i<=n;i++)scanf("%d",&king[i]);memset(g,0,sizeof(g));memset(f,0,sizeof(f));bubblesort(king,n);bubblesort(tian,n);for(i=1;i<=n;i++){for(j=1;j<=n;j++){if(tian[i]>king[j])g[i][j]=200;else if(tian[i]<king[j])g[i][j]=-200;elseg[i][j]=0;}}for(i=1;i<=n;i++){for(j=0;j<=i;j++){if(j==0)f[i][j]=f[i-1][j]+g[n-(i-j)+1][i];else if(i==j)f[i][j]=f[i-1][j-1]+g[j][i];        else    f[i][j]=max(f[i-1][j]+g[n-(i-j)+1][i],f[i-1][j-1]+g[j][i]);        }    }maxx=-200005;for(j=0;j<=n;j++){if(f[n][j]>maxx)maxx=f[n][j];}printf("%d\n",maxx);}}

  

HDU 1052 Tian Ji -- The Horse Racing【貪心在動態規劃中的運用】

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.