UVALive 6912 I Want That Cake

uvalive 6913 dp

题目:

There was an interesting game played on a popular Korean reality TV Show. 12 players in 3 teams
— 4 persons in each team — lined up in one row in random order. The game master approaches the
players one by one starting from the most front player, with a tray full of 31 cakes. Each player should
eat at least 1 and at most 5 cakes during his/her turn. The player who eats the last cake will lose
along with his/her group (this is a team game). It was more an entertainment show rather than a real
competition. The players were selected from “chubby” celebrities who like to eat, thus causing them
in dilemma whether they should win the game (which might require them to hold their urge to eat the
cakes), or just enjoy all 5 cakes ignoring their team member.
This problem is related to the game. There are 2 teams (A and B) each with N players lined up
in a row in random order. Initially there are M cakes in the tray, and each player (starting from the
most front) has to eat at least 1 and at most K cakes during his/her turn. The team whose player eat
the last cake win (note that this is different compared to the original game).
Your task is to determine which team will win the game, given both teams play optimally.
Input
The first line of input contains an integer T (T ≤ 100) denoting the number of cases. Each case begins
with three integers N, M, and K (1 ≤ N ≤ 1, 000; 1 ≤ K ≤ M ≤ 2 ∗ N) in a line denoting the number
of players in each team, the initial number of cakes, and the maximum number of cakes can be eaten
by each player in his/her turn respectively. The next line contains a string S representing the players
order from the front most to the last player. S consists of only character ‘A’ or ‘B’ representing which
team does the respective player belongs to. The length of S is exactly 2 ∗ N and the number of ‘A’ and
‘B’ will be equal.
Output
For each case, output ‘Case #X: Y ’, where X is the case number starts from 1 and Y is ‘A’ if the
game will be won by team A, otherwise ‘B’. Assume both teams will play the game optimally to win
the game.
Explanation for 1st sample case:
The first two players of team A each needs to eat 2 cakes, while the third A player eats the last
cake.
Explanation for 2nd sample case:
No matter what team A do, the last cake will be eaten by one of team B’s player.
Explanation for 3rd sample case:
To ensure their win, the first player (B) should eat 2 cakes, leaving only 3 cakes to the next player
(A). This player (A) should eat at least 1 and at most 2 cakes. No matter how many cakes this player
eats, the next player (B) will eat the last cake.

题意:

有两个队伍,每个队伍各有n个人,现在有m个蛋糕,2*n个人排成一队从左到右一次吃,每个人可以吃[1,k]个蛋糕,恰好吃完所有蛋糕的队伍获胜。

思路:

这个题一眼望去就觉得是一个博弈论,无奈我用博弈论搞了很久,一直是wa,想不到思路哪里错了。看一眼statue,似乎都是dp,就用dp搞了一遍。
首先预处理,把连续的一队的并一起,就得到了一个A,B队伍间隔的序列。
dp[i][j];表示在第i个位置,剩了j个蛋糕时,该队伍能不能赢。
if(cnt[now]*k>=rem)肯定一次吃完。
否则i=cnt[now];i<=cnt[now]*k 枚举所有吃法,如果有一个吃法,他的下一个位置怎么吃都是输,他就肯定选这个,就一定能赢。
否则这一队肯定是输。

#include <iostream>
#include <string.h>
#include <stdio.h>
#define N 2100
using namespace std;
int cnt[N];
int  dp[N][N];
char s[N];
int n,m,k;
bool dfs(int now,int rem)//到第now个人的时候,剩了rem个
{
    if(dp[now][rem]!=-1)return dp[now][rem];//记忆化搜索
    if(cnt[now]*k>=rem)return dp[now][rem]=1;//一次直接吃完
    for(int i=cnt[now];i<=cnt[now]*k;i++)//枚举所有情况
        if(!dfs(now+1,rem-i))return dp[now][rem]=1;
    return dp[now][rem]=0;
}
int main()
{
    int t,cases=1;
    cin>>t;
    while(t--)
    {
        memset(cnt,0,sizeof(cnt));
        scanf("%d%d%d",&n,&m,&k);
        scanf("%s",s);
        cnt[1]=1;
        int sum=1;

        memset(dp,-1,sizeof(dp));
        for(int i=1;i<2*n;i++)
            if(s[i]==s[i-1])
                cnt[sum]++;
            else
                cnt[++sum]=1;
        int  flag=dfs(1,m);//判断是不是第一个胜利
        printf("Case #%d: ",cases++);
        if(flag)
            printf("%c\n",s[0]);
        else
            printf("%c\n",s[0]=='A'? 'B':'A');
    }
    return 0;
}

P.S.
留一下自己当时博弈论wa掉的代码,有思路在回来改吧。orz
组队赛用别人账号交的。。。
大概意思就是从左往右枚举到哪一个人能吃完。
然后对于每一个人,算出如果他能吃完的话,最开始应该有多少个蛋糕的范围,看m是否在这个范围里面。

这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值