HDU 4111Alice and Bob(博弈+记忆化)

来源:互联网 发布:淘宝产品授权书模板 编辑:程序博客网 时间:2024/04/29 03:03

题意:有n堆石子,一次可以拿走一个石子,或者把一堆石子放在另一个石子上。不能再次操作的人输Alice先拿。问谁赢

思路:当石子个数大于1时,可以把他们放到一堆里+1次的操作数。石子数为1时,单独考虑。

设所有只有一个石子的是A堆,其他的石子可以合并的设为B堆。

每一次操作有:

1、把A堆 的两个石子合并。加入到B堆。

2、把B堆的石子减1

3、把A堆的一个石子加入的B堆

4、把A堆的石子减1

可以用记忆化来实现。。


#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <queue>#include <stack>using namespace std;int dp[59][50009];int dfs(int z,int s){    if(dp[z][s]!=-1) return dp[z][s];    if(z==0) return dp[z][s] = s&1;    if(z==1) return dp[1][s]=1;    if(s==1) return dp[z][s] = dfs(z+1,0);    dp[z][s] = 0;    if(!dfs(z-1,s)) dp[z][s] = 1;///直接拿走1个的    if(s>1&&!dfs(z,s-1)) dp[z][s] = 1;    if(s>1&&!dfs(z-1,s+1)) dp[z][s] = 1;    if(z>1&&!dfs(z-2,s?s+3:s+2)) dp[z][s] = 1;///合并之后加入s里    return dp[z][s];}int main(){    freopen("in.txt","r",stdin);    int cas,T=1,n;    scanf("%d",&cas);    memset(dp,-1,sizeof(dp));    while(cas--)    {        scanf("%d",&n);        int z=0,s=0,t=0;        for(int i=0;i<n;i++)        {            scanf("%d",&t);            if(t==1) z++;            else s+=t+1;        }if(s>1) s--;        printf("Case #%d: %s\n",T++,dfs(z,s)?"Alice":"Bob");    }    return 0;}


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 婴儿多大可以竖抱 婴儿多大可以竖着抱 宝宝多大可以竖着抱 婴儿多久可以竖着抱 宝宝多久可以竖着抱 婴儿多久可以竖抱 宝宝多久可以竖抱 3个月宝宝可以竖抱吗 婴儿三个月能竖着抱吗 三个月宝宝能竖抱吗 宝宝几个月能竖着抱 两个月宝宝可以竖着抱吗 两个月宝宝可以竖抱吗 几个月宝宝可以竖抱 几个月宝宝可以竖着抱 三个月宝宝可以竖着抱吗 三个月宝宝可以竖抱吗 新生儿几个月可以竖着抱 婴儿几个月可以竖着抱 婴儿什么时候可以竖着抱 婴儿什么时候可以竖抱 新生儿几个月可以竖抱 宝宝三个月可以竖着抱吗 小孩几个月可以竖着抱 宝宝什么时候可以竖着抱 宝宝什么时候可以竖抱 孩子几个月可以竖着抱 小孩几个月可以竖抱 孩子几个月可以竖抱 宝宝几个月才能竖着抱 三个月的宝宝可以竖着抱吗 两个多月的宝宝可以竖着抱吗 宝宝什么时候能竖着抱 两个月的宝宝可以竖着抱吗 几个月的宝宝可以竖着抱 几个月婴儿可以竖着抱 婴儿三个月可以竖抱吗 2个月的宝宝可以竖着抱吗 小宝宝几个月可以竖着抱 婴儿两个月可以竖抱吗 婴幼儿几个月可以竖着抱