Loading

DP Training K 博弈

DP Training K 博弈

题意

给定正整数集合\(A\),有一个\(K\)个石子的堆,两人轮流取\(x\)个石子,\(x\)\(A\)中元素,问先手还是后手获胜

\[1\leq N \leq100\\ 1\leq K \leq10^5\\ 1 \leq a_i \leq K \]

分析

\(K\)比较小,考虑从\(K\)设计状态

\(dp[i]\)表示当前还剩\(i\)个石子,此时是否处在必胜态

显然\(dp[0] = 0\)

\[dp[i + a[j]] = dp[i + a[j]] | (1 xor dp[j]) \]

对于必败态来说,它加上\(a[j]\)是必胜的,对于必胜态来说却不一定可以转移到必败,因为可以不选

代码

int main(){
	int n = rd();
	int k = rd();
	vector<int> v(n);
	vector<bool> dp(k + 1);
	for(int i = 0;i < n;i++)
		v[i] = rd();
	dp[0] = 0;
	for(int i = 0;i < k;i++){
		for(int j = 0;j < n;j++){
			if(i + v[j] <= k) 
				dp[i + v[j]] = dp[i + v[j]] | (1 ^ dp[i]);
		}
	} 
	cout << (dp[k] ? "First" : "Second");
}
posted @ 2021-02-06 12:20  MQFLLY  阅读(88)  评论(0编辑  收藏  举报