ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

E - Fox and Card Game(博弈论&贪心)

2020-05-05 12:40:02  阅读:265  来源: 互联网

标签:牌堆 nlogn 奇数 int Fox 中间 Game include Card


E - Fox and Card Game(博弈论&贪心)

题意:给nnn堆牌,两人一个人只能从某一个牌堆的牌顶取,一个只能从牌底取,问各自在最优策略下各自取到牌的总和最大。

思路:对每堆牌的奇偶性进行讨论,如果是偶数,那么显然在双方都选最优策略的情况,这堆牌肯定是所有堆中最好的。那么对手为了不让对方不取完这堆最优的牌,对手肯定也会取这堆牌,那么一直取下去,肯定先手取完上半堆,后手取完下半堆牌,再对奇数讨论,与偶数牌堆类似,除了取最中间的那个牌外,两人还是会取一样的牌数,当取到中间牌时,先手会考虑所有奇数牌堆的中间牌谁最大,如果此时的中间牌堆不是最大的,那么先手会选择让对方取这个牌,转而取另一个奇数牌堆的中间牌,后手的策略同理,但由于后手劣势,每次只能取次优的中间牌。

综上结论就出来。先各取一半,然后对所有中间牌sortsortsort一下就好了。

时间复杂度:O(nlogn)O(nlogn)O(nlogn)

AC代码:

#include<cstdio>
#include<vector>
#include<algorithm>
#include<functional> 
using namespace std;
int main(){
	int n,a=0,b=0,num;
	scanf("%d",&n);
	vector<int>v;
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&num);
		int f=num%2,x;num>>=1;//f判断个数为奇数还是偶数. 
		for(int j=0;j<num;j++) 
			scanf("%d",&x),a+=x;
		if(f) scanf("%d",&x),v.push_back(x);
		for(int j=0;j<num;j++)
			scanf("%d",&x),b+=x;
	}
	sort(v.begin(),v.end(),greater<int>());
		for(int i=0;i<v.size();i++)
			if(i&1) b+=v[i];//先手优先取. 
			else a+=v[i];
	printf("%d %d\n",a,b);
	return  0;
}

标签:牌堆,nlogn,奇数,int,Fox,中间,Game,include,Card
来源: https://blog.csdn.net/weixin_45750972/article/details/105914974

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有