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 4111 Alice and Bob (博弈)11年成都现场赛

转载请注明出处,谢谢 http://blog.csdn.net/ACM_cxlove?viewmode=contents           by---cxlove 可惜没有机会去现场做,不过当...
  • ACM_cxlove
  • ACM_cxlove
  • 2012年08月07日 22:32
  • 5771

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

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

hdu-4111-Alice and Bob

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

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
  • 713

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

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

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...
  • zchahaha
  • zchahaha
  • 2017年07月04日 11:15
  • 137

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

题目链接 Alice and Bob Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/O...
  • madaidao
  • madaidao
  • 2014年09月26日 19:24
  • 275

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

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

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

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

hdu4268 Alice and Bob 长春网络赛

Alice and Bob Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...
  • qiqijianglu
  • qiqijianglu
  • 2012年09月09日 10:11
  • 1665
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:HDU 4111 Alice and Bob
举报原因:
原因补充:

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