1. 程式人生 > >noip 2010 三國遊戲

noip 2010 三國遊戲

問題 algo tool marker .org har code i++ 分享

三國遊戲

三國遊戲

描述

小涵很喜歡電腦遊戲,這些天他正在玩一個叫做《三國》的遊戲。
在遊戲中,小涵和計算機各執一方,組建各自的軍隊進行對戰。遊戲中共有N 位武將(N為偶數且不小於4),任意兩個武將之間有一個“默契值”,表示若此兩位武將作為一對組合作戰時,該組合的威力有多大。遊戲開始前,所有武將都是自由的(稱為自由武將,一旦某個自由武將被選中作為某方軍隊的一員,那麽他就不再是自由武將了),換句話說,所謂的自由武將不屬於任何一方。遊戲開始,小涵和計算機要從自由武將中挑選武將組成自己的軍隊,規則如下:小涵先從自由武將中選出一個加入自己的軍隊,然後計算機也從自由武將中選出一個加入計算機方的軍隊。接下來一直按照“小涵→計算機→小涵→??”的順序選擇武將,直到所有的武將被雙方均分完。然後,程序自動從雙方軍隊中各挑出一對默契值最高的武將組合代表自己的軍隊進行二對二比武,擁有更高默契值的一對武將組合獲勝,表示兩軍交戰,擁有獲勝武將組合的一方獲勝。

已知計算機一方選擇武將的原則是盡量破壞對手下一步將形成的最強組合,它采取的具體策略如下:任何時刻,輪到計算機挑選時,它會嘗試將對手軍隊中的每個武將與當前每個自由武將進行一一配對,找出所有配對中默契值最高的那對武將組合,並將該組合中的自由武將選入自己的軍隊。

下面舉例說明計算機的選將策略,例如,遊戲中一共有6 個武將,他們相互之間的默契值如下表所示
技術分享


雙方選將過程如下所示:
技術分享
小涵想知道,如果計算機在一局遊戲中始終堅持上面這個策略,那麽自己有沒有可能必勝?如果有,在所有可能的勝利結局中,自己那對用於比武的武將組合的默契值最大是多少? 假設整個遊戲過程中,對戰雙方任何時候均能看到自由武將隊中的武將和對方軍隊的武將。為了簡化問題,保證對於不同的武將組合,其默契值均不相同。

格式

輸入格式

共N 行。

第一行為一個偶數N(N≤ 500),表示武將的個數。

第2 行到第N 行裏,第(i+1)行有(N?i)個非負整數,每兩個數之間用一個空格隔開,表示i 號武將和i+1,i+2,??,N 號武將之間的默契值(0 ≤ 默契值≤ 1,000,000,000)。

輸出格式

共1 或2 行。

若對於給定的遊戲輸入,存在可以讓小涵獲勝的選將順序,則輸出1,並另起一行輸出。
所有獲勝的情況中,小涵最終選出的武將組合的最大默契值。
如果不存在可以讓小涵獲勝的選將順序,則輸出0。

樣例1

樣例輸入1

6  
5 28 16 29 27 
23 3 20 1 
8 32 26 
33 11 
12

Copy

樣例輸出1

1
32

Copy

樣例2

樣例輸入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

Copy

樣例輸出2

1
77

Copy

限制

每個測試點1s。

提示

樣例1說明:
首先小涵拿走5 號武將;計算機發現5 號武將和剩下武將中的4 號默契值最高,於是拿走4 號;小涵接著拿走3 號;計算機發現3、5 號武將之一和剩下的武將配對的所有組合中,5 號和1 號默契值最高,於是拿走1 號;小涵接著拿走2 號;計算機最後拿走6 號。在小涵手裏的2,3,5 號武將中,3 號和5 號配合最好,默契值為32,而計算機能推出的最好組合為1 號和6 號,默契值為27。結果為小涵勝,並且這個組合是小涵用盡所有方法能取到的最好組合。

來源

NOIP2010普及組

居然是道博弈題 我還想著模擬 慘啊(過於蒟蒻)

看得出小涵是永遠選不到每一個武將所能配對到的最大值的 電腦也一樣啊

所以我們只要能選到次大值裏面的最大值那不是必勝

而且我們是先手所以一定能選到 所以求一波就okay啦

技術分享
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int M=507;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<0||c>9){if(c==-) f=-1; c=getchar();}
    while(c>=0&&c<=9){ans=ans*10+(c-0); c=getchar();}
    return ans*f;
}
int map[M][M],n,ans,k;
int main()
{
    n=read();
    for(int i=1;i<=n;i++){
        for(int j=i+1;j<=n;j++){
            k=read();
            map[i][j]=map[j][i]=k;
        }
    }
    for(int i=1;i<=n;i++){
        int mx1=0,mx2=0;
        for(int j=1;j<=n;j++){
            if(map[i][j]>mx1) mx2=mx1,mx1=map[i][j];
            else mx2=max(mx2,map[i][j]);
        }//printf("[%d %d]\n",mx1,mx2);
        ans=max(ans,mx2);
    }
    printf("1\n%d\n",ans);
    return 0;
}
View Code

noip 2010 三國遊戲