E - Fox and Card Game(博弈論&貪心)

E - Fox and Card Game(博弈論&貪心)

題意:給nn堆牌,兩人一個人只能從某一個牌堆的牌頂取,一個只能從牌底取,問各自在最優策略下各自取到牌的總和最大。

思路:對每堆牌的奇偶性進行討論,如果是偶數,那麼顯然在雙方都選最優策略的情況,這堆牌肯定是所有堆中最好的。那麼對手爲了不讓對方不取完這堆最優的牌,對手肯定也會取這堆牌,那麼一直取下去,肯定先手取完上半堆,後手取完下半堆牌,再對奇數討論,與偶數牌堆類似,除了取最中間的那個牌外,兩人還是會取一樣的牌數,當取到中間牌時,先手會考慮所有奇數牌堆的中間牌誰最大,如果此時的中間牌堆不是最大的,那麼先手會選擇讓對方取這個牌,轉而取另一個奇數牌堆的中間牌,後手的策略同理,但由於後手劣勢,每次只能取次優的中間牌。

綜上結論就出來。先各取一半,然後對所有中間牌sortsort一下就好了。

時間複雜度: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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章