zoukankan      html  css  js  c++  java
  • HDU 4778 Gems Fight!

    Gems Fight!

    Time Limit: 10000ms
    Memory Limit: 327680KB
    This problem will be judged on HDU. Original ID: 4778
    64-bit integer IO format: %I64d      Java class name: Main
     
      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.
     

    Source

     
    解题:记忆化状压搜索
     
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cmath>
     5 #include <algorithm>
     6 #include <climits>
     7 #include <vector>
     8 #include <queue>
     9 #include <cstdlib>
    10 #include <string>
    11 #include <set>
    12 #include <stack>
    13 #define LL long long
    14 #define pii pair<int,int>
    15 #define INF 0x3f3f3f3f
    16 using namespace std;
    17 const int maxn = 22;
    18 int G,B,S,bag[maxn][maxn],dp[1<<maxn];
    19 int dfs(int cur,int sum,int *cooker){
    20     if(cur == 0 || sum <= 0) return 0;
    21     if(dp[cur]) return dp[cur];
    22     int ans = 0;
    23     for(int i = 0; i < B; ++i){
    24         if(cur&(1<<i)){
    25             int sta = cur^(1<<i),ret = 0,tcooker[maxn] = {0};
    26             for(int k = 0; k < maxn; ++k){
    27                 tcooker[k] += cooker[k] + bag[i][k];
    28                 ret += tcooker[k]/S;
    29                 tcooker[k] %= S;
    30             }
    31             if(ret) ans = max(ans,ret+dfs(sta,sum-ret,tcooker));
    32             else ans = max(ans,sum - dfs(sta,sum,tcooker));
    33         }
    34     }
    35     return dp[cur] = ans;
    36 }
    37 int main() {
    38     while(scanf("%d %d %d",&G,&B,&S),G||B||S){
    39         int n,tmp,sum;
    40         int cooker[maxn] = {0};
    41         memset(bag,0,sizeof(bag));
    42         for(int i = 0; i < B; ++i){
    43             scanf("%d",&n);
    44             while(n--){
    45                 scanf("%d",&tmp);
    46                 ++bag[i][tmp];
    47                 cooker[tmp]++;
    48             }
    49         }
    50         for(int i = sum = 0; i < maxn; ++i) sum += cooker[i]/S;
    51         memset(dp,0,sizeof(dp));
    52         memset(cooker,0,sizeof(cooker));
    53         printf("%d
    ",2*dfs((1<<B)-1,sum,cooker) - sum);
    54     }
    55     return 0;
    56 }
    View Code
  • 相关阅读:
    用js完成毫秒格式数据的日期格式化任务
    廖雪峰js教程笔记3
    事务在 更新和 插入中的用法(转自他人)
    左连接 用于 列转行的一个想法
    MyISAM与InnoDB两者之间区别与选择,详细总结,性能对比
    python中的内方法
    波非那切数列
    python修改最大递归数
    odoo开发微信小程序需要的三个包:xmltodict、pycrypto、itsdangerous
    解决json dumps不能序列化datatime数据类型的问题,通过重写JSONEncoder
  • 原文地址:https://www.cnblogs.com/crackpotisback/p/4049756.html
Copyright © 2011-2022 走看看