hdu 4778 Gems Fight!(状态压缩+博弈+记忆化)

Gems Fight!

Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 327680/327680 K (Java/Others)

Total Submission(s): 1383    Accepted Submission(s): 587

Problem Description

  Alice and Bob are playing "Gems Fight!":

  There are Gems of G different colors , packed in B bags. Each bag has several Gems. G different colors are numbered from color 1 to color G.

  Alice and Bob take turns to pick one bag and collect all the Gems inside. A bag cannot be picked twice. The Gems collected are stored in a shared cooker.

  After a player ,we name it as X, put Gems into the cooker, if there are S Gems which are the same color in the cooker, they will be melted into one Magic Stone. This reaction will go on and more than one Magic Stone may be produced, until no S Gems of the
same color remained in that cooker. Then X owns those new Magic Stones. When X gets one or more new Magic Stones, he/she will also get a bonus turn. If X gets Magic Stone in a bonus turn, he will get another bonus turn. In short,a player may get multiple bonus
turns continuously.

  There will be B turns in total. The goal of "Gems Fight!" is to get as more Magic Stones than the opponent as possible.

  Now Alice gets the first turn, and she wants to know, if both of them act the optimal way, what will be the difference between the number of her Magic Stones and the number of Bob‘s Magic Stones at the end of the game.

Input

  There are several cases(<=20).

  In each case, there are three integers at the first line: G, B, and S. Their meanings are mentioned above.

  Then B lines follow. Each line describes a bag in the following format:

  

  n c1 c2 ... cn

  

  It means that there are n Gems in the bag and their colors are color c1,color c2...and color cn respectively.

   0<=B<=21, 0<=G<=8, 0<n<=10, S < 20.

  There may be extra blank lines between cases. You can get more information from the sample input.

  The input ends with G = 0, B = 0 and S = 0.

Output

  One line for each case: the amount of Alice‘s Magic stones minus the amount of Bob‘s Magic Stones.

Sample Input

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

3 2 2
3 2 3 1
3 1 2 3

0 0 0

Sample Output

3
-3

Hint

  For the first case, in turn 2, bob has to choose at least one bag, so that Alice will make a Magic Stone at the end of turn 3, thus get turn 4 and get all the three Magic Stones.

题意:有b个袋子,袋子中装有一些不同颜色的宝石,两个人轮流一个袋子把宝石放入cooker,若有s个宝石颜色相同,这个人得到一分,这 s个宝石消失;且某次得到分数,则可以再取一次。求先手和后手的最大差值。

解题思路:因为最多只有21个袋子,可以考虑状态压缩,且给定袋子宝石数量,可知两个人的总得分是固定的。对于每个状态dp[s]表示当前状态下先手能获得的最大分数,然后,枚举该状态下先手可取的每个袋子作为第一次选择,若选择该袋子能得到分数sum,则先手再取一次,dp[s]=sum+dfs(s^(1<<i),left-sum,c);否则,先手得到分数为当前剩余分数减去后手能得到的分数dp[s]=left-dfs(s^(1<<i),left,c);

#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<queue>
using namespace std;
#define LL __int64
#define N 25
const int inf=-0x1f1f1f1f;
int g,b,s;
int box[25][10];
int dp[1<<21];
int dfs(int S,int left,int c[])
{
    if(dp[S]!=inf)
        return dp[S];
    if(S==0||left==0)
        return 0;
    int ans=0,i;
    int a[10];
    for(i=0;i<b;i++)
    {
        int sum=0;
        if(S&(1<<i))
        {
            int tmp=S^(1<<i),cnt;
            for(int j=1;j<=g;j++)
            {
                a[j]=c[j]+box[i][j];
                sum+=a[j]/s;
                a[j]%=s;
            }
            if(sum)
                cnt=sum+dfs(tmp,left-sum,a);
            else
                cnt=left-dfs(tmp,left,a);
            ans=max(ans,cnt);
        }
    }
    return dp[S]=ans;
}
int main()
{
    int i,x,m;
    int num[10];
    while(scanf("%d%d%d",&g,&b,&s),g||b||s)
    {
        memset(box,0,sizeof(box));
        memset(num,0,sizeof(num));
        for(i=0;i<b;i++)
        {
            scanf("%d",&m);
            while(m--)
            {
                scanf("%d",&x);
                box[i][x]++;
                num[x]++;
            }
        }
        int sum=0;
        for(i=1;i<=g;i++)
            sum+=num[i]/s;
        for(i=0;i<(1<<b);i++)
            dp[i]=inf;
        int c[10];
        memset(c,0,sizeof(c));
        int ans=dfs((1<<b)-1,sum,c);
        printf("%d\n",ans*2-sum);
    }
    return 0;
}
时间: 2024-10-11 17:23:50

hdu 4778 Gems Fight!(状态压缩+博弈+记忆化)的相关文章

hdu 4778 Gems Fight!(状态压缩DP)

又是一道状态压缩,刚开始老是往博弈的方法想,总是没思路. #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N=21; const int inf=0x3f3f3f3f; int g,n,s; int sum[1<<N]; int res[10]; int c[22][10]; i

hdu 4628 Pieces(状态压缩+记忆化搜索)

Pieces Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 1811    Accepted Submission(s): 932 Problem Description You heart broke into pieces.My string broke into pieces.But you will recover one

HDU 4778 Gems Fight!(dp)

HDU 4778 Gems Fight! 题目链接 题意:有n个背包,包里有一些宝石,现在爱丽丝和你轮流选背包,把包里宝石丢到锅中,然后如果锅中有宝石数量到s个,就会得到魔法石,并且可以继续选背包,两人都按最优策略去取,问最后两人魔法石会差多少. 思路:dp,dp[s]表示选背包状态为s时候的值,然后去记忆化搜索即可,注意如果当前生成魔法石就继续加,否则就减即可 代码: #include <stdio.h> #include <string.h> #include <algo

hdu 4778 Rabbit Kingdom(状态压缩)

题目链接:hdu 4778 Rabbit Kingdom 题目大意:Alice和Bob玩游戏,有一个炉子,可以将S个相同颜色的宝石换成一个魔法石,现在有B个包,每个包里有若干个宝石,给出宝石的颜色.现在由Alice开始,两人轮流选取一个包的宝石放入炉中,每当获得一个魔法石时,可以额外获得一次机会再选一个包放入.两人均按照自己的最优策略,问说最后Alice的魔法石-Bob的魔法石是多少. 解题思路:状态压缩,221,对于每次移动到下一个状态,如果获得的魔法石g非零,则说明下一个状态还是自己在取,则

hdu 4778 Gems Fight! 状压dp

转自wdd :http://blog.csdn.net/u010535824/article/details/38540835 题目链接:hdu 4778 状压DP 用DP[i]表示从i状态选到结束得到的最大值 代码也来自wdd 1 /****************************************************** 2 * File Name: b.cpp 3 * Author: kojimai 4 * Creater Time:2014年08月13日 星期三 11时

(状压dp)HDU 4778 Gems Fight!

Gems Fight! Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 327680/327680 K (Java/Others)Total Submission(s): 2395    Accepted Submission(s): 1087 Problem Description Alice and Bob are playing "Gems Fight!": There are Gems of G differe

hdu1143 状态压缩dp 记忆化搜索写法

http://poj.org/problem?id=1143 Description Christine and Matt are playing an exciting game they just invented: the Number Game. The rules of this game are as follows. The players take turns choosing integers greater than 1. First, Christine chooses a

vijos - P1456最小总代价 (状态压缩DP + 记忆化搜索)

P1456最小总代价 Accepted 标签:[显示标签] 描述 n个人在做传递物品的游戏,编号为1-n. 游戏规则是这样的:开始时物品可以在任意一人手上,他可把物品传递给其他人中的任意一位:下一个人可以传递给未接过物品的任意一人. 即物品只能经过同一个人一次,而且每次传递过程都有一个代价:不同的人传给不同的人的代价值之间没有联系: 求当物品经过所有n个人后,整个过程的总代价是多少. 格式 输入格式 第一行为n,表示共有n个人(16>=n>=2): 以下为n*n的矩阵,第i+1行.第j列表示物

[博弈dp] hdu 4778 Gems Fight

给出g种颜色的宝石,然后有B个背包,S代表到时候每种颜色的宝石凑齐S个能变成一个魔法石 然后B行数输入,每个包里有哪些宝石 然后A,B轮流拿包,每个包只能拿一次,拿出包把宝石放地上. 如果能变成魔法石则拿走魔法石,下一次还这个人拿包,没变成则换人. 魔法石的个数就是获得分数,问两人最优的时候分差是多少. 思路: 只有21个包,状压dp. 然后发现不管顺序如何 最后构成的魔法石的个数是一定的. 然后在不同的二进制状态下,所剩在地面上的宝石是一定的. 那么就可以dp[i] 代表i这个状态下 先手取所