zoukankan      html  css  js  c++  java
  • HDU 4778 Gems Fight! (2013杭州赛区1009题,状态压缩,博弈)

    Gems Fight!

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


    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.
     
    Source
     

    时限比较多。

    二进制表示状态,然后处理就可以了。

    dp[1<<21] 

    dp[i]表示现在状态是i,先手-后手的分数。

    枚举i里面存在的位j,   i & (1<<j) != 0

     如果取了j, 增加了,那么就是 + dp[i ^ (1<<j)]

    否则是  - dp[i ^ (1<<j)]

    表示换人了。

     1 /* ***********************************************
     2 Author        :kuangbin
     3 Created Time  :2013-11-9 12:55:09
     4 File Name     :E:2013ACM专题强化训练区域赛2013杭州1009.cpp
     5 ************************************************ */
     6 
     7 #include <stdio.h>
     8 #include <string.h>
     9 #include <iostream>
    10 #include <algorithm>
    11 #include <vector>
    12 #include <queue>
    13 #include <set>
    14 #include <map>
    15 #include <string>
    16 #include <math.h>
    17 #include <stdlib.h>
    18 #include <time.h>
    19 using namespace std;
    20 
    21 int c[22][20];
    22 int b[20];
    23 int d[20];
    24 int dp[1<<22];
    25 int main()
    26 {
    27     //freopen("in.txt","r",stdin);
    28     //freopen("out.txt","w",stdout);
    29     int G,B,S;
    30     int n,t;
    31     while(scanf("%d%d%d",&G,&B,&S) == 3)
    32     {
    33         if(G == 0 && B == 0 && S == 0)break;
    34         memset(c,0,sizeof(c));
    35         for(int i = 0;i < B;i++)
    36         {
    37             scanf("%d",&n);
    38             while(n--)
    39             {
    40                 scanf("%d",&t);
    41                 c[i][t]++;
    42             }
    43         }
    44         dp[0] = 0;
    45         int tot = (1<<B);
    46         for(int i = 1;i < tot;i++)
    47         {
    48             dp[i] = -10000000;
    49             for(int j = 1;j <= G;j++)
    50                 b[j] = 0;
    51             for(int j = 0;j < B;j++)
    52                 if((i&(1<<j)) == 0)
    53                 {
    54                     for(int k = 1;k <= G;k++)
    55                     {
    56                         b[k] += c[j][k];
    57                         while(b[k] >= S)
    58                             b[k] -= S;
    59                     }
    60                 }
    61             //cout<<i<<"*"<<endl;
    62             //for(int j = 1;j <= G;j++)
    63                 //cout<<b[j]<<endl;
    64             for(int j = 0;j < B;j++)
    65                 if(i & (1<<j))
    66                 {
    67                     for(int k = 1;k <= G;k++)
    68                         d[k] = b[k];
    69                     int cnt = 0;
    70                     for(int k = 1;k <= G;k++)
    71                     {
    72                         d[k] += c[j][k];
    73                         while(d[k] >= S)
    74                         {
    75                             d[k] -= S;
    76                             cnt++;
    77                         }
    78                     }
    79                     if(cnt > 0)dp[i] = max(dp[i],cnt + dp[i^(1<<j)]);
    80                     else dp[i] = max(dp[i],cnt - dp[i^(1<<j)]);
    81                 }
    82 
    83         }
    84         printf("%d
    ",dp[tot-1]);
    85     }
    86     return 0;
    87 }
  • 相关阅读:
    ajax 中$.each(json,function(index,item){ }); 中的2个参数表示什么意思?
    后台传list到前台,前台怎么解析,怎么将解析的数据填充到已经存在列名table中
    mybatis如何直接 执行传入的任意sql语句 并按照顺序取出查询的结果集
    虚拟机突然无法 联网,最简单及最可能的原因
    windows10,nodejs安装步骤
    Windows下Git与Node.js的安装
    Windows10下安装Git的详细教程
    django-admin.py startproject testdj 失败 没有工程文件夹
    在Pythonfor循环中如何获取循环次数?
    Pygal之世界地图绘制from pygal.i18n import COUNTRIES 报错的解决办法
  • 原文地址:https://www.cnblogs.com/kuangbin/p/3416196.html
Copyright © 2011-2022 走看看