hdu4778状态压缩

Posted Billyshuai

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu4778状态压缩相关的知识,希望对你有一定的参考价值。

Gems Fight!

Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 327680/327680 K (Java/Others)
Total Submission(s): 2482    Accepted Submission(s): 1126


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
 
 
这个是消耗空间换时间的
 
 
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int dp[(1<<21)+55][9];
int G,B,S,v[25][10],a[10];
int main(){
    while(scanf("%d%d%d",&G,&B,&S),G+B+S){
        memset(v,0,sizeof(v));
        memset(a,0,sizeof(a));
        for(int i=0;i<B;++i) {
            int x,n;
            for(scanf("%d",&n);n--;){
                scanf("%d",&x);
                v[i][x]++;
                a[x]++;
                a[x]%=S;
            }
        }
        int mm=(1<<B)-1;
        for(int i=1;i<=G;++i) dp[0][i]=a[i];
        dp[0][0]=0;
        for(int i=1;i<=mm;++i) dp[i][0]=-10000000;
        for(int i=0;i<=mm;++i) for(int j=0;j<B;++j) {
            int x=(1<<j);
            if(!(i&x)) {
                int gs=0;
                for(int k=1;k<=G;++k) {
                    a[k]=dp[i][k]-v[j][k];
                    while(a[k]<0) {
                        gs++;
                        a[k]+=S;
                    }
                    dp[i^x][k]=a[k];
                }
                if(gs>0) dp[i^x][0]=max(dp[i^x][0],gs+dp[i][0]);
                else dp[i^x][0]=max(dp[i^x][0],-dp[i][0]);
            }
        }
        printf("%d\\n",dp[mm][0]);
    }

}

 

 

这个是消耗时间换空间的

http://www.cnblogs.com/kuangbin/p/3416196.html

 

 

/* ***********************************************
Author        :kuangbin
Created Time  :2013-11-9 12:55:09
File Name     :E:\\2013ACM\\专题强化训练\\区域赛\\2013杭州\\1009.cpp
************************************************ */

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;

int c[22][20];
int b[20];
int d[20];
int dp[1<<22];
int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int G,B,S;
    int n,t;
    while(scanf("%d%d%d",&G,&B,&S) == 3)
    {
        if(G == 0 && B == 0 && S == 0)break;
        memset(c,0,sizeof(c));
        for(int i = 0;i < B;i++)
        {
            scanf("%d",&n);
            while(n--)
            {
                scanf("%d",&t);
                c[i][t]++;
            }
        }
        dp[0] = 0;
        int tot = (1<<B);
        for(int i = 1;i < tot;i++)
        {
            dp[i] = -10000000;
            for(int j = 1;j <= G;j++)
                b[j] = 0;
            for(int j = 0;j < B;j++)
                if((i&(1<<j)) == 0)
                {
                    for(int k = 1;k <= G;k++)
                    {
                        b[k] += c[j][k];
                        while(b[k] >= S)
                            b[k] -= S;
                    }
                }
            //cout<<i<<"*"<<endl;
            //for(int j = 1;j <= G;j++)
                //cout<<b[j]<<endl;
            for(int j = 0;j < B;j++)
                if(i & (1<<j))
                {
                    for(int k = 1;k <= G;k++)
                        d[k] = b[k];
                    int cnt = 0;
                    for(int k = 1;k <= G;k++)
                    {
                        d[k] += c[j][k];
                        while(d[k] >= S)
                        {
                            d[k] -= S;
                            cnt++;
                        }
                    }
                    if(cnt > 0)dp[i] = max(dp[i],cnt + dp[i^(1<<j)]);
                    else dp[i] = max(dp[i],cnt - dp[i^(1<<j)]);
                }

        }
        printf("%d\\n",dp[tot-1]);
    }
    return 0;
}

 

以上是关于hdu4778状态压缩的主要内容,如果未能解决你的问题,请参考以下文章

(状压dp)HDU 4778 Gems Fight!

HDU1024 经典DP+状态压缩

hdu4064 三进制状态压缩 好题!

HDU 6607 Time To Get Up(状态压缩+枚举)

hdu 1074 状态压缩

HDU 3247 Resource Archiver (AC自己主动机 + BFS + 状态压缩DP)