zoukankan      html  css  js  c++  java
  • 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
    ",cas);
            else
                printf("Case #%d: Bob
    ",cas);
        }
    }
  • 相关阅读:
    python学习----8.28---单例模式,网络编程
    python学习-----8.27----异常处理,元类
    python学习--8.23
    python学习-----8.22--classmethod和staticmethod
    Python学习---8.21组合,多态,封装
    python学习----8.20面向对象---继承与派生
    Python学习----8.17--面向对象编程
    python成长之旅 一
    python java php语言之间的对比
    python成长之旅
  • 原文地址:https://www.cnblogs.com/qscqesze/p/4521254.html
Copyright © 2011-2022 走看看