Luogu 三国游戏

Luogu P1199 三国游戏

  • 首先,我们要知道一个事情,人的脑子是活的,而电脑是死的

  • 这题代码其实不难写,难的在于如何证明贪心的正确性。

    • 首先我们可以知道小涵是先手,所以他要选择拥有最大默契度的两个武将之一,那AI肯定不愿意啊,不然他怎么能当个AI,如果小涵拿到了整场比赛默契值最大的武将,那AI根本就不用继续了,小涵就不会喜欢这游戏了,这太无聊了(和题目中所说小涵喜欢这游戏相矛盾,由此可证)。所以,作为一个强大的AI,他要去破环与小涵所选的武将的默契值最大的武将。无奈的小涵只能选择和他所选武将默契值次大的武将。
    • 上述说的是前3步的情况,也是最普遍的情况。根据普遍情况,我们可以推出,AI会选择场上能和小涵手中武将组成最大默契值的武将,注意!是场上未选择的武将。如果觉得上面说的话比较绕的话不妨来看一组栗子:
    • 来解释下这个栗子,小涵不给长脸,直接一手选了拥有全场最高默契1,2号武将中的1号武将。AI也不是吃素的啊,直接反手选了能够和1号武将有最高默契的2号武将,小涵比较无奈地选择了与1号武将默契次大的3号武将。这步AI走地就比较关键了,通过栗子我们可以看出:1号武将和4号武将的默契值大于3号武将和5号武将的默契值,所以会选择4号武将。
    • AI作为后手并由于其鸡肋的操作规则,通过栗子我们可以证明出:小涵一定可以拿到场上任意一武将X的次大默契值武将Y,而这个最大值是场上的最大默契值。所以第一个问题一定输出1,也就是说小涵一定获胜。就像栗子里,1号武将的次大默契值武将是3号武将,而1号和3号武将的默契值是场上的最大默契值(小涵是个人不是个机器人)。根据结论,我们只需要将每个武将的默契值武将排序,并将每个武将次大的默契值取个最大值 \(ans=max(ans,a[i][n-1]);\),就是小涵可以拿到的最高分。
  • 接下来就是一点也不激动人心的代码了:

#include<bits/stdc++.h>
using namespace std;
template<class t> inline t read(t &x){
	char c=getchar();bool f=0;x=0;
	while(!isdigit(c)) f|=c=='-',c=getchar();
	while(isdigit(c))x=(x<<1)+(x<<3)+(c^48),c=getchar();
	if(f)x=-x;return x;
}
template<class t>inline void write(t x){
	if(x<0)putchar('-'),write(-x);
	else{if(x>9)write(x/10);putchar('0'+x%10);}
}
template<class t>inline void writeln(t x){
	write(x);putchar('\n');
	return;
}
template<class t>inline void write_blank(t x){
	write(x);putchar(' ');
	return;
}
int n,a[510][510],ans=-1; 
int main(){
	read(n);
	for(int i=1;i<=n-1;i++){
		for(int j=i+1;j<=n;j++){
			read(a[i][j]);
			a[j][i]=a[i][j];
		}
	}
	for(int i=1;i<=n;i++){
		sort(a[i]+1,a[i]+1+n);
		ans=max(ans,a[i][n-1]);
	}
	printf("1\n");
	write(ans);
	return 0;
}

posted @ 2020-05-05 19:22  半笙、凡尘  阅读(320)  评论(0编辑  收藏  举报