HODJ 4111 Alice and Bob(博弈)

题目:http://acm.hdu.edu.cn/showproblem.php?pid=4111

题意:有N堆石头,可以把两堆合成一堆,也可以把一堆去掉一个。

由于总数不变,最终总是要一个个拿完。那么有机会获胜的一方,肯定是先要把所有的合在一起,那么最终就拼奇偶数了。所以双方都要合并。总共就是sigma(ai)+n-1

然而,特殊情况出现了。当某些堆石子只有一颗的时候呢?只要本来要输的那个人有机会将这颗石子拿走,本来要赢的那个孩子就没有机会将这一堆合并了!整体奇偶性一改变,输家可能变成了赢家!

因此把一颗石子一堆的情况单独拎出来,剩下的合并成一堆。状态为sg[i][j]i代表有i1颗石子组成的小堆,j代表剩下石子合并成一个大堆后的个数。每个状态最多有四种后继:1、拿走大堆的一颗石子。2、拿走一个小堆。3、将一个小堆和大堆合并。4、将两个小堆合并

sg[i][j]=mex{ sg[i][j-1],sg[i-1][j],sg[i-1][j+1],sg[i-2][j+3](j!=0) sg[i-2][2](j=0)}

注意一下状态转移的条件即可。

由于只是单个游戏,因此不需要计算sg值,只需标记必胜必败点即可

代码:

#include

#include

#include

using namespace std;

int dp[55][50010];

int Win(int i,int j){

    if(dp[i][j]!=-1){

        return dp[i][j];

    }

    if(j==1){      

        return dp[i][j]=Win(i+1,0);

    }

    dp[i][j]=0;

    //某堆只有一个的取掉

    if(i>=1&&!Win(i-1,j)){

        return dp[i][j]=1;

    }

    //把不是1个的取走一个

    else if(j>=1&&!Win(i,j-1)){

        return dp[i][j]=1;

    }

    //1个的合并给不是1个的

    else if(i>=1&&j>0&&!Win(i-1,j+1)){

        return dp[i][j]=1;

    }

    //把两个1个的合并,其中注意,合并是需要一步的

    if(i>=2&&(j==0&&!Win(i-2,j+2)||j>=1&&!Win(i-2,j+3))){

        return dp[i][j]=1;

    }

    return dp[i][j];

}

int main(){

    //freopen("C:\\Users\\Administrator\\Desktop\\001.txt","r",stdin);

    int n,t,k=1;

    int one,sum,temp;

    cin>>t;

      memset(dp,-1,sizeof(dp));

    while(t--){

        cin>>n;

        one=0;

        sum=0;

        while(n--){

            cin>>temp;

            if(temp==1)

                one++;

            else{

                sum+=(temp+1);

            }

        }

        if(sum){

            sum--;

        }

        cout<<"Case #"<<k++<<": ";

        if(Win(one,sum)){

            cout<<"Alice"<<endl;

        }

        else{

            cout<<"Bob"<<endl;

        }

    }

    return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值