题目链接:hdu 4778 Rabbit Kingdom

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

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

C++ 记忆化版
#include <cstdio>
#include <cstring>
#include <algorithm> using namespace std; const int maxb = 21;
const int maxn = 1<<21;
const int maxg = 10;
const int INF = 0x3f3f3f3f; int G, B, S;
int c[maxb+5][maxg], s[maxn+5][maxg];
int v[maxn+5], dp[maxn+5]; void init () {
int t, a;
memset(c, 0, sizeof(c));
memset(v, 0, sizeof(v)); for (int i = 0; i < B; i++) {
scanf("%d", &t);
for (int j = 0; j < t; j++) {
scanf("%d", &a);
c[i][a]++;
}
} for (int i = 0; i < (1<<B); i++) {
for (int j = 0; j < B; j++) { if (i&(1<<j))
continue; int e = i|(1<<j); if (v[e])
continue; for (int k = 1; k <= G; k++)
s[e][k] = (s[i][k] + c[j][k]) % S;
}
}
} int add (int k, int x) {
int ans = 0;
for (int i = 1; i <= G; i++)
ans += (s[k][i] + c[x][i]) / S;
return ans;
} int dfs (int u) { if (u + 1 == (1<<B))
return 0; if (v[u])
return dp[u]; int up = -INF;
int lower = INF; for (int i = 0; i < B; i++) {
if (u&(1<<i))
continue; int g = add (u, i); if (g)
up = max(up, dfs(u|(1<<i))+g);
else
lower = min(lower, dfs(u|1<<i));
}
v[u] = 1;
return dp[u] = max(up, -lower);
} int main () {
while (scanf("%d%d%d", &G, &B, &S) == 3 && G + B + S) {
init();
memset(v, 0, sizeof(v));
printf("%d\n", dfs(0));
}
return 0;
}
C++ 递推版
#include <cstdio>
#include <cstring>
#include <algorithm> using namespace std; const int maxb = 21;
const int maxn = 1<<21;
const int maxg = 10;
const int INF = 0x3f3f3f3f; int G, B, S;
int c[maxb+5][maxg], s[maxn+5][maxg];
int v[maxn+5], dp[maxn+5]; void init () {
int t, a;
memset(c, 0, sizeof(c));
memset(v, 0, sizeof(v)); for (int i = 0; i < B; i++) {
scanf("%d", &t);
for (int j = 0; j < t; j++) {
scanf("%d", &a);
c[i][a]++;
}
} for (int i = 0; i < (1<<B); i++) {
for (int j = 0; j < B; j++) { if (i&(1<<j))
continue; int e = i|(1<<j); if (v[e])
continue; for (int k = 1; k <= G; k++)
s[e][k] = (s[i][k] + c[j][k]) % S;
}
}
} int add (int k, int x) {
int ans = 0;
for (int i = 1; i <= G; i++)
ans += (s[k][i] + c[x][i]) / S;
return ans;
} int solve () {
int e = (1<<B) - 1;
memset(dp, -INF, sizeof(dp));
dp[e] = 0; for (int u = e; u >= 0; u--) { for (int i = 0; i < B; i++) {
if ((u&(1<<i)) == 0)
continue; int ui = u-(1<<i);
int g = add(ui, i); if (g)
dp[ui] = max(dp[ui], dp[u] + g);
else
dp[ui] = max(dp[ui], -dp[u]);
}
}
return dp[0];
} int main () {
while (scanf("%d%d%d", &G, &B, &S) == 3 && G + B + S) {
init();
printf("%d\n", solve());
}
return 0;
}

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

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. 浏览器hack总结 详细的浏览器兼容性解决方法

    由于各浏览器对页面的解析不同,会导致页面在不同浏览器中显示的样式不一致,为了保持页面的统一,经常需要对浏览器进行兼容性问题的调试. CSS Hack 面对浏览器诸多的兼容性问题,经常需要通过CSS样式 ...

  2. JAVAC 命令使用方法

    结构 javac [ options ] [ sourcefiles ] [ @files ] 參数可按随意次序排列. options 命令行选项. sourcefiles 一个或多个要编译的源文件( ...

  3. 飞翔(LIS变形)

    飞翔 时间限制:3000 ms  |  内存限制:65535 KB 难度:4 描述 鹰最骄傲的就是翱翔,但是鹰们互相都很嫉妒别的鹰比自己飞的快,更嫉妒其他的鹰比自己飞行的有技巧.于是,他们决定举办一场 ...

  4. 2014 International Conference on Robotics and Computer Vision (ICRVC 2014)

    2014机器人与计算机视觉国际会议ICRVC 与会地点:北京 与会时间:2014.10.24-26 截稿日期:2014-07-10 关于征稿: 语言:英文 主题: • Evolutionary Rob ...

  5. InheritableThreadLocal

    InheritableThreadLocal继承自ThreadLocal,但比ThreadLocal多一个特性: 子线程可以继承父亲线程上下文中的信息 但是,有两个点需要注意的: 只有子线程创建之前的 ...

  6. Excel VBA ——批量工作表重命名

    虽然平常在用excel 2010重命名工作表的时候,一般可能会用"双击工作表"的方法来重名,但是遇到大批量重名的时候就很麻烦. 我的方法,先建一张新表,然后在第一列写好要命名的表名 ...

  7. BZOJ 1014: [JSOI2008]火星人prefix( splay + hash )

    用splay维护序列, 二分+hash来判断LCQ.. #include<bits/stdc++.h> using namespace std; typedef unsigned long ...

  8. jsp_javabean

    什么是javabean? 遵循一定的设计原则的任何java类都可以是javabean组件 1.可序列化 implements serializable 2.无参数的构造方法 3.私有属性 通过公有方法 ...

  9. 标准I/O库函数的缺陷

    标准IO库存在着两个缺陷.首先,它是在某一台特定类型的机器上实现的,而没有考虑其他的具有不同特性的机器.这样就可能导致在其中的一台机器上运行很好的程序,在另外一台机器上却出现错误,而这其中的原因仅仅是 ...

  10. 如何在VMware中修改Mac OS的屏幕分辨率

    关于mac os分辨率问题:方法一:临时方法,只对当次启动有效,即在启动倒计时的时候,回车,等待输入参数是输入如下文本:“Graphics Mode"="1280x800x32@6 ...