题目链接:hdu 4778 Rabbit Kingdom

题目大意:Alice和Bob玩游戏,有一个炉子。能够将S个同样颜色的宝石换成一个魔法石。如今有B个包,每一个包里有若干个宝石,给出宝石的颜色。如今由Alice開始,两人轮流选取一个包的宝石放入炉中,每当获得一个魔法石时,能够额外获得一次机会再选一个包放入。两人均依照自己的最优策略。问说最后Alice的魔法石-Bob的魔法石是多少。

解题思路:状态压缩,221,对于每次移动到下一个状态,假设获得的魔法石g非零。则说明下一个状态还是自己在取。则要选择最优的。假设g为0。则说明下一个状态不是自己在取,则要取尽量小的,相应也就是相反数尽量大的。

  1. C++ 记忆化版
  2.  
  3. #include <cstdio>
  4. #include <cstring>
  5. #include <algorithm>
  6. using namespace std;
  7. const int maxb = 21;
  8. const int maxn = 1<<21;
  9. const int maxg = 10;
  10. const int INF = 0x3f3f3f3f;
  11. int G, B, S;
  12. int c[maxb+5][maxg], s[maxn+5][maxg];
  13. int v[maxn+5], dp[maxn+5];
  14. void init () {
  15. int t, a;
  16. memset(c, 0, sizeof(c));
  17. memset(v, 0, sizeof(v));
  18. for (int i = 0; i < B; i++) {
  19. scanf("%d", &t);
  20. for (int j = 0; j < t; j++) {
  21. scanf("%d", &a);
  22. c[i][a]++;
  23. }
  24. }
  25. for (int i = 0; i < (1<<B); i++) {
  26. for (int j = 0; j < B; j++) {
  27. if (i&(1<<j))
  28. continue;
  29. int e = i|(1<<j);
  30. if (v[e])
  31. continue;
  32. for (int k = 1; k <= G; k++)
  33. s[e][k] = (s[i][k] + c[j][k]) % S;
  34. }
  35. }
  36. }
  37. int add (int k, int x) {
  38. int ans = 0;
  39. for (int i = 1; i <= G; i++)
  40. ans += (s[k][i] + c[x][i]) / S;
  41. return ans;
  42. }
  43. int dfs (int u) {
  44. if (u + 1 == (1<<B))
  45. return 0;
  46. if (v[u])
  47. return dp[u];
  48. int up = -INF;
  49. int lower = INF;
  50. for (int i = 0; i < B; i++) {
  51. if (u&(1<<i))
  52. continue;
  53. int g = add (u, i);
  54. if (g)
  55. up = max(up, dfs(u|(1<<i))+g);
  56. else
  57. lower = min(lower, dfs(u|1<<i));
  58. }
  59. v[u] = 1;
  60. return dp[u] = max(up, -lower);
  61. }
  62. int main () {
  63. while (scanf("%d%d%d", &G, &B, &S) == 3 && G + B + S) {
  64. init();
  65. memset(v, 0, sizeof(v));
  66. printf("%d\n", dfs(0));
  67. }
  68. return 0;
  69. }
  1. C++ 递推版
  2.  
  3. #include <cstdio>
  4. #include <cstring>
  5. #include <algorithm>
  6. using namespace std;
  7. const int maxb = 21;
  8. const int maxn = 1<<21;
  9. const int maxg = 10;
  10. const int INF = 0x3f3f3f3f;
  11. int G, B, S;
  12. int c[maxb+5][maxg], s[maxn+5][maxg];
  13. int v[maxn+5], dp[maxn+5];
  14. void init () {
  15. int t, a;
  16. memset(c, 0, sizeof(c));
  17. memset(v, 0, sizeof(v));
  18. for (int i = 0; i < B; i++) {
  19. scanf("%d", &t);
  20. for (int j = 0; j < t; j++) {
  21. scanf("%d", &a);
  22. c[i][a]++;
  23. }
  24. }
  25. for (int i = 0; i < (1<<B); i++) {
  26. for (int j = 0; j < B; j++) {
  27. if (i&(1<<j))
  28. continue;
  29. int e = i|(1<<j);
  30. if (v[e])
  31. continue;
  32. for (int k = 1; k <= G; k++)
  33. s[e][k] = (s[i][k] + c[j][k]) % S;
  34. }
  35. }
  36. }
  37. int add (int k, int x) {
  38. int ans = 0;
  39. for (int i = 1; i <= G; i++)
  40. ans += (s[k][i] + c[x][i]) / S;
  41. return ans;
  42. }
  43. int solve () {
  44. int e = (1<<B) - 1;
  45. memset(dp, -INF, sizeof(dp));
  46. dp[e] = 0;
  47. for (int u = e; u >= 0; u--) {
  48. for (int i = 0; i < B; i++) {
  49. if ((u&(1<<i)) == 0)
  50. continue;
  51. int ui = u-(1<<i);
  52. int g = add(ui, i);
  53. if (g)
  54. dp[ui] = max(dp[ui], dp[u] + g);
  55. else
  56. dp[ui] = max(dp[ui], -dp[u]);
  57. }
  58. }
  59. return dp[0];
  60. }
  61. int main () {
  62. while (scanf("%d%d%d", &G, &B, &S) == 3 && G + B + S) {
  63. init();
  64. printf("%d\n", solve());
  65. }
  66. return 0;
  67. }

版权声明:本文博客原创文章,博客,未经同意,不得转载。

hdu 4778 Rabbit Kingdom(减少国家)的更多相关文章

  1. HDU 4777 Rabbit Kingdom(树状数组)

    HDU 4777 Rabbit Kingdom 题目链接 题意:给定一些序列.每次询问一个区间,求出这个区间和其它数字都互质的数的个数 #include <cstdio> #include ...

  2. HDU 4777 Rabbit Kingdom (2013杭州赛区1008题,预处理,树状数组)

    Rabbit Kingdom Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  3. HDU 4777 Rabbit Kingdom --容斥原理+树状数组

    题意: 给一个数的序列,询问一些区间,问区间内与区间其他所有的数都互质的数有多少个. 解法: 直接搞有点难, 所谓正难则反,我们求区间内与其他随便某个数不互质的数有多少个,然后区间长度减去它就是答案了 ...

  4. HDU 4777 Rabbit Kingdom 树状数组

    分析:找到每一个点的左边离他最近的不互质数,记录下标(L数组),右边一样如此(R数组),预处理 这个过程需要分解质因数O(n*sqrt(n)) 然后离线,按照区间右端点排序 然后扫一遍,对于当前拍好顺 ...

  5. HDU 4777 Rabbit Kingdom

    素因子分解,树状数组.$ACM/ICPC$ $2013$杭州区域赛$H$题. 首先需要处理出数字$a[i]$左边最远到$L[i]$,右边最远到$R[i]$区间内所有数字都与$a[i]$互质. 那么对于 ...

  6. hdu 4778 Gems Fight! 博弈+状态dp+搜索

    作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4102743.html 题目链接:hdu 4778 Gems Fight! 博弈+状态dp+搜 ...

  7. hdu 5030 Rabbit&#39;s String(后缀数组&amp;二分法)

    Rabbit's String Time Limit: 40000/20000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others ...

  8. HDU 4778 状压DP

    一看就是状压,由于是类似博弈的游戏.游戏里的两人都是绝对聪明,那么先手的选择是能够确定最终局面的. 实际上是枚举最终局面情况,0代表是被Bob拿走的,1为Alice拿走的,当时Alice拿走且满足变换 ...

  9. hdu 4778 Gems Fight! 状压dp

    转自wdd :http://blog.csdn.net/u010535824/article/details/38540835 题目链接:hdu 4778 状压DP 用DP[i]表示从i状态选到结束得 ...

随机推荐

  1. QT全平台设置图标,全平台静态编译 good

    1.  概述 当我们用QT写好了一个软件,要把你的程序分享出去的时候,不可能把编译的目录拷贝给别人去运行.编译好的程序应该是一个主程序,加一些资源文件,再加一些动态链接库,高大上一些的还可以做一个安装 ...

  2. [cocos2d-x]针对不同的设备,选取不同的自适应图片

    前言: 我们在进行移动设备开发的时候,我们常常会准备不同大小的图片资源以适应不同大小的设备,下面我称普清图片资源和高清图片资源.那么如何做到图片资源的自适应呢?下面我来用一个demo展示一下这个效果的 ...

  3. 【LeetCode】Repeated DNA Sequences 解题报告

    [题目] All DNA is composed of a series of nucleotides abbreviated as A, C, G, and T, for example: &quo ...

  4. 梳理一下重装sql2008R2sp1步骤

    我的电脑是这样,最早的时候装的是2005,后来公司用到2008,我就手动卸载,但是好像卸载的不够彻底,在装2008的时候,选择升级方式安装. 虽然成功了,但是在运行select @@version 时 ...

  5. js中with、this的用法

    with 语句 为一个或一组语句指定默认对象. 用法:with (<对象>) <语句>; with 语句通常用来缩短特定情形下必须写的代码量.在下面的例子中,请注意 Math ...

  6. 基于visual Studio2013解决C语言竞赛题之0614递归大元素

     题目 解决代码及点评 /************************************************************************/ /* 14. 编一个程 ...

  7. load data 方式导入的数据不可以用binlog日志进行恢复,因为binlog里面不产生insert sql语句。

    QQ群里面有人问起这个问题:    用load data 导入数据的时候,在binlog文件中记录的不是insert 语句,这样的话,如果用load data 导入数据,当需要恢复数据库的时候  bi ...

  8. java--函数练习

    /* 1,定义一个功能,用于打印矩形 1,定义一个打印九九乘法表功能的函数 */ class FunctionTest { public static void main(String[] args) ...

  9. Eclipse Package Explorer视图无法打开

    打开Eclipse后Package Explorer视图无法打开,显示一个红叉,红叉后面的Deatils后,显示下面的内容: java.lang.ArrayIndexOutOfBoundsExcept ...

  10. encode_utf8 把字符编码成字节 decode_utf8解码UTF-8到字符

    encode_utf8 $octets = encode_utf8($string); Equivalent to "$octets = encode("utf8", $ ...