题意:
给一个数n和m个数d[m],现在A和B轮流进行操作,不能进行操作的人为输,规则如下:
1.第一步A写一个0,设s[1]=0,第二步B令s[2]=s[1]+d[i]
2.两人轮流从d数组中任选一个数d[k],令s[i]=s[i-1]+d[k]或者s[i]=s[i-1]-d[k];
3.s[i]>s[i-2]并且s[i]<=n
思路;
从最终状态开始看,假设min是d中最小的数,如果s[i]+min>n,那么游戏结束,所以游戏的最后一步一定是s[i]=s[i-1]+min之后使得s[i]+min>n,至于为什么不能s[i]-d[i](违反了第三规则),所以对于任何一个状态如果我选择的不是min那么对手总可以减去min来使自己进行一次操作,但是如果我选min,对手就只能往上加。所以对于两个人的最好的策略就是每次都加一个min,看谁先不能加即可。
#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
int main()
{
int T;cin>>T;
int n,m,x;
int Case=1;
while(T--)
{
cin>>n>>m;
int minn = INF;
for(int i=0;i<m;i++)
{
cin>>x;
if(x<minn)
minn = x;
}
cout<<"Case #"<<Case++<<": ";
int ans = n/minn;
if(ans%2==0)
cout<<"Alice"<<endl;
else
cout<<"Bob"<<endl;
}
return 0;
}