Time Limit: 6666MS | Memory Limit: Unknown | 64bit IO Format: %lld & %llu |
Description
![Download as PDF Download as PDF](https://i-blog.csdnimg.cn/blog_migrate/2ea975a8d421ce3226c46b0946fd5932.png)
Problem B: Bachet's Game
![](http://uva.onlinejudge.org/external/104/p10404.jpg)
Here we consider a variation of this game. The number of stones that can be removed in a single move must be a member of a certain set of m numbers. Among the m numbers there is always 1 and thus the game never stalls.
Input
The input consists of a number of lines. Each line describes one game by a sequence of positive numbers. The first number is n <= 1000000 the number of stones on the table; the second number is m <= 10 giving the number of numbers that follow; the last m numbers on the line specify how many stones can be removed from the table in a single move.Input
For each line of input, output one line saying either Stan wins or Ollie wins assuming that both of them play perfectly.Sample input
20 3 1 3 8 21 3 1 3 8 22 3 1 3 8 23 3 1 3 8 1000000 10 1 23 38 11 7 5 4 8 3 13 999996 10 1 23 38 11 7 5 4 8 3 13
Output for sample input
Stan wins Stan wins Ollie wins Stan wins Stan wins Ollie wins
解决方案:首先,若最后Stan面对能一次拿完的石头数,则胜,初始化胜点为这几个,然后由这个往后推,若Stan能按照规定拿走石头,达到的败点,则这个点为胜点。dp[i]={1|若存在dp[i-a[j]]==0}。
code:
#include <iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=1000006;
int dp[maxn];
int a[13];
int main()
{
int M,n;
while(~scanf("%d",&M))
{
memset(dp,0,sizeof(dp));
scanf("%d",&n);
for(int i=1; i<=n; i++)
{
scanf("%d",&a[i]);
dp[a[i]]=1;
}
for(int i=1; i<=M; i++)
for(int j=1; j<=n; j++)
{
if(i>=a[j]&&!dp[i-a[j]])
dp[i]=!dp[i-a[j]];
}
if(dp[M]){
printf("Stan wins\n");
}
else{
printf("Ollie wins\n");
}
}
return 0;
}