HDU 4111 Alice and Bob

原创 2016年08月30日 17:22:20

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


题意:有n堆石子,每堆有ai个,现在可以选择一堆拿走一个,或者合并两堆。问谁能赢。


思路:

如果全部的堆数都大于1,那么一定是把石子全部合并后一个个取走,因为输的人没法一次取走一堆,而赢的人每次把最少的合并起来。

dp[i][j]表示有i堆为1的石子,j是所有大于1堆的石子的总操作数 j = ∑ai + m - 1  m为大于1堆石子的堆数,表示这m堆石子一共可以操作这么多次。

那么考虑所有的操作:

1、对大于1的堆进行(拿走/或者合并两个大于1的堆)=>  dp[i][j-1]

2、拿走一个“1”堆 => dp[i-1][j]

3、合并两个"1"堆 =>dp[i-2][2] / dp[i-2][j+3]  ( j = 0 / j != 0 )

4、把一个"1"堆合并到一个大于1的堆里 => dp[i-1][j+1]

记忆化搜索即可。


#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <sstream>
#include <queue>
#include <utility>
using namespace std;

#define rep(i,j,k) for (int i=j;i<=k;i++)
#define Rrep(i,j,k) for (int i=j;i>=k;i--)

#define Clean(x,y) memset(x,y,sizeof(x))
#define LL long long
#define ULL unsigned long long
#define inf 0x7fffffff
#define mod 100000007

int f[55][55555];
int n;
int ans;

int dfs( int x , int y )
{
    if ( f[x][y] != -1 ) return f[x][y];
    int ans = 0;
    if ( y == 1 ) return f[x][y] = dfs( x + 1 , 0 );
    if ( x == 0 ) return y & 1;
    if ( y > 1 ) //非1堆中进行操作
        ans = max( ans , 1-dfs( x , y - 1 ) );
    if ( x >= 1 ) //取走1
        ans = max( ans , 1-dfs( x - 1 , y ) );
    if ( x >= 2 ) //合并两堆"1"
        ans = max( ans , y==0?!dfs( x - 2 , 2 ) : 1-dfs( x - 2 , y + 3 ) );
    if ( x >= 1 && y > 1 ) //合并“1”和非1
        ans = max( ans , 1-dfs( x - 1 , y + 1 ) );
    return f[x][y] = ans;
}

void init()
{
    scanf("%d",&n);
    int temp,sum,num;
    num = sum = 0;
    rep(i,1,n)
    {
        scanf("%d",&temp);
        if ( temp == 1 ) num++;
        else sum += temp;
    }

    ans = dfs( num , sum + n - num - 1 );
}

int main()
{
    Clean(f,-1);
    f[0][0] = 0;
    int T;
    cin>>T;
    rep(kase,1,T)
    {
        init();
        printf("Case #%d: %s\n",kase,ans?"Alice":"Bob");
    }
    return 0;
}






版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

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

题意:有n堆石子,一次可以拿走一个石子,或者把一堆石子放在另一个石子上。不能再次操作的人输Alice先拿。问谁赢 思路:当石子个数大于1时,可以把他们放到一堆里+1次的操作数。石子数为1时,单独考虑...

hdu-4111-Alice and Bob

题意:n堆不同数量的石头 A,B两人可进行如下两种操作 1. 拿走其中一堆的其中一个石头 2.合并任意两堆石头 A先,直达轮到某人事,他无法进行任何操作,结束,并判该人输。 题解: 无论石头...

Hdu4111Alice and Bob(dp+博弈论)

Alice and Bob Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...
  • modiz
  • modiz
  • 2014年08月06日 20:40
  • 685

HDU 4111 Alice and Bob (博弈[记忆话搜索])

题意: 给你n 堆石子,两种操作: 1. 任选一堆石子, 数目减一, 如果为0 删除这一堆。 2. 任选两堆石子进行合并。 最后不能操作的人输掉。 问谁能赢? 思路: 记忆话搜索博弈,第...

hdu 4111 Alice and Bob 博弈论 sg函数

Problem Description Alice and Bob are very smart guys and they like to play all kinds of games in t...

Hdu 4111 Alice and Bob(博弈+记忆化搜索)

题目链接 Alice and Bob Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/O...

解题报告:HDU 4111 Alice and Bob 递推|博弈

题目链接 题意: 现在有n堆石子,每堆石子分别有A1,A2,A3...An个 现在有两种操作: 1.选一堆非空石子将其数量减一 2.合并两个非空石子 Alice 和 Bob 轮流进行操作,先取完的...

HDU4268 2012ACM长春赛区网络赛 Alice and Bob

题目:HDU4268(贪心) 比赛的时候没做出来,后来几天也没做这个题,今天搞了一下午,参考了几大牛人的博客,才弄懂.. 题意是Alice和Bob都有N张卡片,卡片各有尺寸,Alice拿自己的卡片...
  • ifinver
  • ifinver
  • 2012年09月18日 17:37
  • 901

hdu4268 Alice and Bob 长春网络赛

Alice and Bob Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

hdu 5054 Alice and Bob

Alice and Bob Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:HDU 4111 Alice and Bob
举报原因:
原因补充:

(最多只允许输入30个字)