hdu 4111 Alice and Bob 记忆化搜索 博弈论

Alice and Bob

Time Limit: 20 Sec  Memory Limit: 256 MB

题目连接

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

Description

Alice and Bob are very smart guys and they like to play all kinds of games in their spare time. The most amazing thing is that they always find the best strategy, and that‘s why they feel bored again and again. They just invented a new game, as they usually did.
The rule of the
new game is quite simple. At the beginning of the game, they write down N
random positive integers, then they take turns (Alice first) to either:
1. Decrease a number by one.
2. Erase any two numbers and write down their sum.
Whenever
a number is decreased to 0, it will be erased automatically. The game
ends when all numbers are finally erased, and the one who cannot play in
his(her) turn loses the game.
Here‘s the problem: Who will win the
game if both use the best strategy? Find it out quickly, before they get
bored of the game again!

Input

The first line contains an integer T(1 <= T <= 4000), indicating the number of test cases.
Each test case contains several lines.
The first line contains an integer N(1 <= N <= 50).
The next line contains N positive integers A1 ....AN(1 <= Ai <= 1000), represents the numbers they write down at the beginning of the game.

Output

For each test case in the input, print one line: "Case #X: Y", where X is the test case number (starting with 1) and Y is either "Alice" or "Bob".

Sample Input

3 3 1 1 2 2 3 4 3 2 3 5

Sample Output

Case #1: Alice
Case #2: Bob
Case #3: Bob

HINT

题意

给你n堆石头,你有两个选择,1.减少一堆石头数量1,2.合并两堆石头

如果遇到不能操作的情况就算输

题解:

这道题当成dp来做,dp[i][j]表示现在有i堆只有1个,j表示现在我能够操作次数

操作次数等于 sigma(a[i])-n+1,其中a[i]>1,n为满足条件的a[i]的个数

------------------------

那么转移方程就出来了,1个的,要么消去,要么和1个的合并,要么和多个的合并

然后就可以记忆化搜索搞了

代码:

//qscqesze
#include <cstdio>
#include <cmath>
#include <cstring>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <set>
#include <vector>
#include <sstream>
#include <queue>
#include <typeinfo>
#include <fstream>
#include <map>
#include <stack>
typedef long long ll;
using namespace std;
//freopen("D.in","r",stdin);
//freopen("D.out","w",stdout);
#define sspeed ios_base::sync_with_stdio(0);cin.tie(0)
#define maxn 50051
#define mod 10007
#define eps 1e-9
int Num;
char CH[20];
//const int inf=0x7fffffff;   //нчоч╢С
const int inf=0x3f3f3f3f;
/*

inline void P(int x)
{
    Num=0;if(!x){putchar(‘0‘);puts("");return;}
    while(x>0)CH[++Num]=x%10,x/=10;
    while(Num)putchar(CH[Num--]+48);
    puts("");
}
*/
inline ll read()
{
    ll x=0,f=1;char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
    while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
    return x*f;
}
inline void P(int x)
{
    Num=0;if(!x){putchar(‘0‘);puts("");return;}
    while(x>0)CH[++Num]=x%10,x/=10;
    while(Num)putchar(CH[Num--]+48);
    puts("");
}
//**************************************************************************************

int dp[100][maxn];
int a[maxn];

int dfs(int a,int b)//a 表示还有多少组为1  b表示还剩下多少次操作次数
{
    if(dp[a][b]!=-1)
        return dp[a][b];
    dp[a][b]=0;//其他情况都是不可操作的
    if(b==1)
        return dp[a][b]=dfs(a+1,0);//只剩一个单独的一,加入其它1中
    if(a>=1&&!dfs(a-1,b))//直接去掉一个1
        dp[a][b]=1;
    if(a>=1&&b&&!dfs(a-1,b+1))//将一个1合到其它数中
        dp[a][b]=1;
    if(a>=2&&((b&&!dfs(a-2,b+3))||(b==0&&!dfs(a-2,2))))//将2个1并起来
        dp[a][b]=1;
    if(b>=2&&!dfs(a,b-1))//减小一
        dp[a][b]=1;  

    return dp[a][b];
}  

int main()
{
    //freopen("test.txt","r",stdin);
    memset(dp,-1,sizeof(dp));
    int t=read();
    for(int cas=1;cas<=t;cas++)
    {
        int flag=0;
        int sum=0;
        int n=read();
        for(int i=0;i<n;i++)
        {
            a[i]=read();
            if(a[i]==1)
                flag++;
            else
                sum+=a[i]+1;
        }
        sum--;
        dfs(flag,sum);
        if(dp[flag][sum])
            printf("Case #%d: Alice\n",cas);
        else
            printf("Case #%d: Bob\n",cas);
    }
}
时间: 2024-08-05 11:12:21

hdu 4111 Alice and Bob 记忆化搜索 博弈论的相关文章

HDU 4597 Play Game (记忆化搜索)

题意:有两堆n张的卡片,每张卡片有一个得分,Alice和Bob轮流在两堆卡片的两端取卡片 问Alice先手,取得分数最多为多少: #include <stdio.h> #include <iostream> #include <algorithm> #include <string.h> #include <queue> #include <math.h> #define M 50 #define LL long long using

hdu 1501 Zipper (dfs+记忆化搜索)

Zipper Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6491    Accepted Submission(s): 2341 Problem Description Given three strings, you are to determine whether the third string can be formed

hdu 4597 Play Game【记忆化搜索】

Play Game Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) Total Submission(s): 805    Accepted Submission(s): 464 Problem Description Alice and Bob are playing a game. There are two piles of cards. There are N card

HDU 1078 FatMouse and Cheese(记忆化搜索DP)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1078 题目大意:一个n*n的图,每个点都有奶酪,老鼠从(0,0)开始走,每次最多只能走k步就要停下来,停下的这个位置的奶酪数只能比上一个停留的位置大,并获取其奶酪,每次只能水平或垂直走,问最多能得到的奶酪. 解题思路:记忆化搜索,这方面还是写的太少,还要看别人才会,这个就当个例子参考吧. 1 #include<cstdio> 2 #include<cstring> 3 #include

hdu 1142(迪杰斯特拉+记忆化搜索)

A Walk Through the Forest Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 7330    Accepted Submission(s): 2687 Problem Description Jimmy experiences a lot of stress at work these days, especiall

HDU 1428 漫步校园 (BFS + 记忆化搜索)

漫步校园 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 3360    Accepted Submission(s): 1009 Problem Description LL最近沉迷于AC不能自拔,每天寝室.机房两点一线.由于长时间坐在电脑边,缺乏运动.他决定充分利用每次从寝室到机房的时间,在校园里散散步.整个HDU校园呈方形布局,可

hdu 1176免费馅饼(记忆化搜索)

题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1176 题意不解释了 简单的记忆化搜索可以拿来练练手,注意要从pos = 5 开始搜索 #include <iostream> #include <cstring> #include <algorithm> #include <cstdio> #include <cmath> using namespace std; const int M = 1e5

HDU 2476 String painter(记忆化搜索, DP)

题目大意: 给你两个串,有一个操作! 操作时可以把某个区间(L,R) 之间的所有字符变成同一个字符.现在给你两个串A,B要求最少的步骤把A串变成B串. 题目分析: 区间DP, 假如我们直接想把A变成B,那么我们DP区间的时候容易产生一个问题:假如我这个区间更新了,那么之前这个区间的子区间内DP出来的值就没用. 然后考虑到这里一直想不过去.最后看了看题解才知道. 我们可以先预处理一下怎么将一个空串变成B串需要的操作数. 这样我们就不用考虑子区间被覆盖的情况了. 如区间L,R 我们需要考虑的是点L是

!HDU 1078 FatMouse and Cheese-dp-(记忆化搜索)

题意:有一个n*n的格子.每一个格子里有不同数量的食物,老鼠从(0,0)開始走.每次下一步仅仅能走到比当前格子食物多的格子.有水平和垂直四个方向,每一步最多走k格,求老鼠能吃到的最多的食物. 分析: 矩阵上求最大子路线和,可是不像一维的最大子序列那么easy,由于二维的确定不了计算顺序. 既然不能确定计算顺序,那么就能够利用dp记忆化搜索,这个正好不用管计算顺序: dp记忆化搜索的思想:递归,然后通过记录状态dp[i][j]是否已经计算过来保证每一个状态仅仅计算一次避免反复计算.若计算过则返回d