洛谷
P1199 [NOIP2010 普及组] 三国游戏
题目链接
题意:
中文题面都不想看?
思路:
博弈论,如果玩家选择了一个武将,电脑会选择和他组合后默契值最高的那个武将,我们肯定想要拿到组合后次大的武将,然后电脑再拿一个武将,之后我们就妨碍电脑拿武将就可以了。
这样的话,我们要做的就是保证前两次拿到的默契值最大,这肯定是第一个武将次大的默契值,而且电脑前两次拿到的不如我们的大,因为我们后面一直在妨碍电脑,所以电脑拿不到每个武将最大的默契值,最多就拿到次大的默契值。而我们拿到的是最大的次大值,所以后面电脑拿到的肯定不如我们的大。这样,我们只需要保证电脑前两次拿到的不如我们的大就行了。
把我们和电脑第一次拿到的两个武将挑出看,这两个武将最大的默契值是一致的,而且不会被我们和电脑拿到,而我们拿到的是其中一个武将的次大值,电脑拿到的是另一个次大值,既然我们选择的是最大的次大值的武将,那么我们的肯定比电脑大。
其实上面这里我们在顾虑电脑前两次拿到是另外两个武将的最大值,它可能比我们手上最大的次大值要大,其实这是不可能的,因为电脑拿到的第一个武将的最大值已经被糟践掉了,拿第二个武将组合出来的最多也就是第一个武将的次大值。所以我们放心大胆选次大值最大的武将就行了,不用管最大值是什么。
code:(有点丑陋)
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn=505;
inline int read(){
int x;
scanf("%d",&x);
return x;
}
int n,a[maxn][maxn];
int main(){
n=read();
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
a[i][j]=a[j][i]=read();
int maxx,cmaxx,ans=0;
for(int i=1;i<=n;i++){
maxx=cmaxx=0;
for(int j=1;j<=n;j++){
if(a[i][j]>=maxx){
cmaxx=maxx;
maxx=a[i][j];
}
else if(a[i][j]>cmaxx){
cmaxx=a[i][j];
}
}
ans=max(ans,cmaxx);
}
printf("1\n%d",ans);
return 0;
}