Alice和Bob在玩这样一个游戏。给定k个数字a[1],a[2],…,a[k]。一开始,有x枚硬币,Alice和Bob轮流取硬币。每次所取硬币的枚数一定要在a[1],a[2],…,a[k]当中。Alice先取,取走最后一枚硬币的一方获胜。当双方都采取最优策略时,谁会获胜?题目假定a[1],a[2],…,a[k]中一定有1。
限制条件:
1<=x<=10000
1<=k<=100
1<=a[i]<=x
输入:
x=9
k=2
a={1,4}
输出:
Alice
输入:
x=10
k=2
a={1,4}
输出:
Bob
#include <iostream>
#include <cstdio>
using namespace std;
#define MAXN 12000
int a[120];
int win[MAXN]; //win表示的是先手的必胜必败态
int main()
{
int x,k;
int i,j;
scanf("%d",&x);
scanf("%d",&k);
for(i=1;i<=k;i++)
{
scanf("%d",&a[i]);
}
win[0]=0; //0个硬币 先手肯定没硬币拿啊,
//这也给我们启示,首先要考虑没有硬币的情况。
for(j=1;j<=x;j++)
{
win[j]=0;
for(i=1;i<=k;i++)
{
win[j]=(a[i]<=j&&win[j-a[i]]==0); //原理:j-a[i]是必败态的话,j就是必胜态,逆向递推
if(win[j])
break;
} // j-a[i]是必胜态的话,j就是必败态
} // a[i]<=j说明还有硬币可以拿,
// j-a[i]是必败态
if(win[x]) // 与的话a如果>j的话,就直接结束了。
printf("Alice\n");
else
printf("Bob\n");
return 0;
}