DP Training K 博弈

DP Training K 博弈

题意

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

[1leq N leq100\ 1leq 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");
}
原文地址:https://www.cnblogs.com/hznumqf/p/14381133.html