zoukankan      html  css  js  c++  java
  • uvalive6913 I Want That Cake(博弈dp)

    引自:http://www.cnblogs.com/qscqesze/p/5734143.html

    题意:

    有两支队,每只队都有n个人,一共有m个蛋糕,每个人至少吃一个,最多吃k个。

    都采取最优策略,谁吃到最后一个蛋糕,那么那只队就胜利。

    按照给定的顺序去吃蛋糕,问你最后谁胜利。

    思路:

    先缩点,把相同的点都缩成一个点。

    那么就变成了ABABABA这样交替的形式了,然后跑DP就好了。

    dp[i][j]代表第i层代表的队伍蛋糕还剩j个时的状态

    0为必败态,1为必胜态

    首先,能把蛋糕吃完的状态为必胜态

    然后,能到达必败态的状态为必胜态

    只能到达必胜态的状态为必败态

    递归回0,m的状态,如果为必胜态则输出第一个吃蛋糕的队伍

    否则输出第二个吃蛋糕的队伍

    /* ***********************************************
    Author        :devil
    ************************************************ */
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <set>
    #include <stack>
    #include <map>
    #include <string>
    #include <cmath>
    #include <stdlib.h>
    #define LL long long
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    #define dep(i,a,b) for(int i=a;i>=b;i--)
    #define ou(a) printf("%d
    ",a)
    #define pb push_back
    #define mkp make_pair
    template<class T>inline void rd(T &x)
    {
        char c=getchar();
        x=0;
        while(!isdigit(c))c=getchar();
        while(isdigit(c))
        {
            x=x*10+c-'0';
            c=getchar();
        }
    }
    #define IN freopen("in.txt","r",stdin);
    #define OUT freopen("out.txt","w",stdout);
    using namespace std;
    const int inf=0x3f3f3f3f;
    const int mod=1e9+7;
    const int N=2e3+10;
    char s[N];
    int dp[N][N],t,n,m,k,cas;
    vector<int>eg;
    bool dfs(int x,int y)
    {
        if(y<=0) return 0;
        if(x==eg.size()) return 1;
        if(dp[x][y]!=-1) return dp[x][y];
        int &ans=dp[x][y];
        ans=0;
        for(int i=eg[x]*k;i>=eg[x];i--)
            if(!dfs(x+1,y-i))
                return ans=1;
        return ans;
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        IN
    #endif
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d%d%s",&n,&m,&k,s+1);
            printf("Case #%d: ",++cas);
            n<<=1;
            eg.clear();
            memset(dp,-1,sizeof(dp));
            for(int i=1;i<=n;)
            {
                int j=i+1;
                while(j<=n&&s[j]==s[i]) j++;
                eg.pb(j-i);
                i=j;
            }
            if(dfs(0,m)) printf("%c
    ",s[1]);
            else printf("%c
    ",s[1]=='A'?'B':'A');
        }
        return 0;
    }
  • 相关阅读:
    为DataGrid 写一个 DropDownListColumn
    网页向女友告白和纪念日专用特效
    CentOS6.5 64位站点压力測试工具webbench
    RxJava系列之二 变换类操作符具体解释1
    C语言实现单链表节点的删除(带头结点)
    excel 补全全部空格
    Linux经常使用命令-文件搜索命令-文件搜索命令find
    错误代码: 1045 Access denied for user &#39;skyusers&#39;@&#39;%&#39; (using password: YES)
    Yocto tips (17): Yocto License问题:restricted license not whitelisted in LICENSE_FLAGS_WHITELIST
    二叉树的基本使用
  • 原文地址:https://www.cnblogs.com/d-e-v-i-l/p/5988215.html
Copyright © 2011-2022 走看看