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