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");
}