ACM 竞赛高校联盟 练习赛 第六场 卡牌游戏(博弈论+思维)

链接:https://nanti.jisuanke.com/t/16877

分析:考虑单独的一堆,数量为s。首先每个人都有把握可以取到离自己最近的一半,如果对手的最优策略是取属于我方的那一半,那么可以跟着对方取,让对手不能得逞。如果s为偶数,那么没得抢;如果s为奇数,先手可以抢到中间的那一张,因此,最优策略是抢大小为奇数且中间的牌最大的那一堆,然后后手抢第二大的,一次类推。。排个序按顺序取即可。

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<algorithm>
 5 #include<vector>
 6 using namespace std;
 7 vector<int> card[105];
 8 int n;
 9 bool Cmp(vector<int> a,vector<int> b){
10     if(a.size()%2==0)return false;
11     if(b.size()%2==0)return true;
12     return a[a.size()/2]>b[b.size()/2];
13 }
14 int main(){
15 //    freopen("e:\in.txt","r",stdin);
16     int s,sum=0,hmm=0,t;
17     scanf("%d",&n);
18     for(int i=0;i<n;i++){
19         scanf("%d",&s);
20         for(int j=0;j<s;j++){
21             scanf("%d",&t);
22             card[i].push_back(t);
23             sum+=t;
24         }
25     }    sort(card,card+n,Cmp);
26     int idx=0;
27     while(idx<n){
28         for(int j=0;j<card[idx].size()/2;j++){
29             hmm+=card[idx][j];
30         }
31         if(card[idx].size()%2==1&&idx%2==0)hmm+=card[idx][card[idx].size()/2];
32         idx++;
33     }
34     if(hmm*2>sum)cout<<"win"<<endl;
35     else if(hmm*2==sum)cout<<"tie"<<endl;
36     else cout<<"lose"<<endl;
37     return 0;
38 }
原文地址:https://www.cnblogs.com/7391-KID/p/7478799.html