洛谷 1199三國遊戲
題目描述
小涵很喜歡電腦遊戲,這些天他正在玩一個叫做《三國》的遊戲。
在遊戲中,小涵和計算機各執一方,組建各自的軍隊進行對戰。遊戲中共有 N 位武將(N為偶數且不小於 4),任意兩個武將之間有一個“默契值”,表示若此兩位武將作為一對組合作戰時,該組合的威力有多大。遊戲開始前,所有武將都是自由的(稱為自由武將,一旦某個自由武將被選中作為某方軍隊的一員,那麽他就不再是自由武將了),換句話說,所謂的自由武將不屬於任何一方。
遊戲開始,小涵和計算機要從自由武將中挑選武將組成自己的軍隊,規則如下:小涵先從自由武將中選出一個加入自己的軍隊,然後計算機也從自由武將中選出一個加入計算機方的軍隊。接下來一直按照“小涵→計算機→小涵→……”的順序選擇武將,直到所有的武將被雙方均分完。然後,程序自動從雙方軍隊中各挑出一對默契值最高
的武將組合代表自己的軍隊進行二對二比武,擁有更高默契值的一對武將組合獲勝,表示兩軍交戰,擁有獲勝武將組合的一方獲勝。
已知計算機一方選擇武將的原則是盡量破壞對手下一步將形成的最強組合,它采取的具體策略如下:任何時刻,輪到計算機挑選時,它會嘗試將對手軍隊中的每個武將與當前每個自由武將進行一一配對,找出所有配對中默契值最高的那對武將組合,並將該組合中的自由武將選入自己的軍隊。 下面舉例說明計算機的選將策略,例如,遊戲中一共有 6 個武將,他們相互之間的默契值如下表所示:
雙方選將過程如下所示:
小涵想知道,如果計算機在一局遊戲中始終堅持上面這個策略,那麽自己有沒有可能必
勝?如果有,在所有可能的勝利結局中,自己那對用於比武的武將組合的默契值最大是多
少? 假設整個遊戲過程中,對戰雙方任何時候均能看到自由武將隊中的武將和對方軍隊的武將。為了簡化問題,保證對於不同的武將組合,其默契值均不相同。
輸入輸出格式
輸入格式:
輸入文件名為 sanguo.in,共 N 行。
第一行為一個偶數 N,表示武將的個數。
第 2 行到第 N 行裏,第(i+1)行有(Ni)個非負整數,每兩個數之間用一個空格隔
開,表示 i 號武將和 i+1,i+2,……,N 號武將之間的默契值(0≤默契值≤1,000,000,000)。
輸出格式:
輸出文件 sanguo.out 共 1 或 2 行。
若對於給定的遊戲輸入,存在可以讓小涵獲勝的選將順序,則輸出 1,並另起一行輸出
所有獲勝的情況中,小涵最終選出的武將組合的最大默契值。
如果不存在可以讓小涵獲勝的選將順序,則輸出 0。
輸入輸出樣例
輸入樣例#1:【輸入樣例1】 6 5 28 16 29 27 23 3 20 1 8 32 26 33 11 12 【輸入樣例2】 8 42 24 10 29 27 12 58 31 8 16 26 80 6 25 3 36 11 5 33 20 17 13 15 77 9 4 50 19輸出樣例#1:
【輸出樣例1】 1 32 【輸出樣例2】 1 77
說明
【數據範圍】
對於 40%的數據有 N≤10。
對於 70%的數據有 N≤18。
對於 100%的數據有 N≤500。
這是一道博倫題,題目這麽長,其實代碼才二十幾行。
首先來分析一下這道題目
由於是否勝利取決於默契值最高的武將組合,所以除了默契值最大的一組,其他的武將都沒有用,所以只需要考慮選兩組。
因為小涵先選,並且題目要求輸出默契值盡量大的,所以只要一開始選擇最優方案,之後也就可以不用考慮了。
繼續深入分析,就會發現,小涵是輸不了的。因為小涵永遠掌握主動權,計算機一直都只是選擇與小涵所選的武將搭配中默契值最大的。
舉個例子:小涵選一個將,計算機選走搭配默契值最大的武將,然後小涵選走默契值次大的武將,計算機把小涵選走的兩個武將中剩下搭配方案裏默契值最大的選走。到這裏就已經定下了勝負。 此時,如果計算機的最大默契值比小涵的小,那麽毫無疑問小涵就贏了。而如果計算機的武將搭配默契值比小涵的大,那麽小涵完全可以在選擇第二個武將時從計算機的方案的角度選,得到更優方案。
依此類推,所以無論如何,小涵總會贏。
代碼:
1 #include<algorithm> 2 #include<iostream> 3 #include<cstdio> 4 using namespace std; 5 int n; 6 int moqi[505][505],f[505],a[505]; 7 int main() 8 { 9 cin>>n; 10 for(int i=1;i<=n;i++) 11 for(int j=i+1;j<=n;j++) 12 { 13 cin>>moqi[i][j]; 14 moqi[j][i]=moqi[i][j]; 15 } 16 for(int i=1;i<=n;i++) 17 { 18 for(int j=1;j<=n;j++) 19 a[j]=moqi[i][j]; 20 sort(a+1,a+n+1); 21 f[i]=a[n-1]; 22 } 23 sort(f+1,f+n+1); 24 cout<<1<<endl<<f[n]; 25 return 0; 26 }
洛谷 1199三國遊戲