K-Stones 简单的博弈问题
题面:
有 K 个石子,双方轮流取石子,每一次取的石子数必须是集合 A 中的一个数,双方都以最优策略行动,判断先手必胜还是后手必胜。
输入格式
第一行给定集合 A A A 的长度 N N N ,石子数 K K K 。
第二行输入集合 A = { A 1 , A 2 , A 3 , … … , A N } A ={A_1,A_2,A_3,……,A_N} A={A1,A2,A3,……,AN}
如图:
输出格式
First
代表先手胜,Second
代表后手胜
思路:
设置 d p [ i ] : dp[i]: dp[i]: 取 i i i 颗石子的胜负情况, d p [ i ] dp[i] dp[i] 为真则先手胜,否则后手胜。
重点是找到破题点:剩余的石子中可以被一次刚好拿完的记下来,由此看一看剩 k k k 个石子时能不能赢。
感觉像是记忆化搜索(递推)。
code:
// K - Stones
// Writen by Jrz
#include<iostream>
#include<cstdio>
int n,k,dp[100003];
int v[101];
int main(){
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)scanf("%d",&v[i]);
for(int i=1;i<=k;i++){
int ok=0;
for(int j=1;j<=n;j++){
if(i<v[j])continue;
if(dp[i-v[j]]==0){
ok=1;break;
}
}
dp[i]=ok;
}
if(dp[k])printf("First");
else printf("Second");
}