UVA 10404 (Bachet's Game)

【题意】给出总石子数n,和m堆石子,两个人轮着取石子,每次只能从总石子中取m堆中的一堆的个数的石子,取走最后一个石子的胜。S先取,O后取。

【解题思路】这个题我不会,网查大牛做法,好巧妙!!!

【状态表示】dp[i]表示当前剩余石子数为i的时候,1表示s取胜,0表示o取胜!

【状态转移】。转移方程为当 i -a[j]>=0而且dp【i - a[j]】=0(0<=j<m),dp【i】=1;

【总结】实质就是考虑当前s的必胜态由哪个o的必败态转移而来!

【AC代码】

#include <stdio.h>
#include <time.h>
using namespace std;
int a[11];
bool dp[1000001];
int main()
{
    int n,m;
    while(~scanf("%d",&n))
    {
        scanf("%d",&m);
        for(int i=0; i<m; i++)scanf("%d",&a[i]);
        dp[0]=0;
        for(int i=1; i<=n; i++)
        {
            dp[i]=0;
            for(int j=0; j<m; j++)
            {
                if(i>=a[j]&&dp[i-a[j]]==0)
                {
                    dp[i]=1;
                    break;
                }
            }
        }
        if(dp[n])puts("Stan wins");
        else
            puts("Ollie wins");
    }
    return 0;
}


你可能感兴趣的:(UVA 10404 (Bachet's Game))