题目链接:hdu 4777 Rabbit Kingdom
题目大意:Alice和Bob玩游戏,有一个炉子,可以将S个相同颜色的宝石换成一个魔法石,现在有B个包,每个包里有若干个宝石,给出宝石的颜色。现在由Alice开始,两人轮流选取一个包的宝石放入炉中,每当获得一个魔法石时,可以额外获得一次机会再选一个包放入。两人均按照自己的最优策略,问说最后Alice的魔法石-Bob的魔法石是多少。
解题思路:状态压缩,221,对于每次移动到下一个状态,如果获得的魔法石g非零,则说明下一个状态还是自己在取,则要选择最优的。如果g为0,则说明下一个状态不是自己在取,则要取尽量小的,对应也就是相反数尽量大的。
C++ 记忆化版#include
#include
#include
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<
C++ 递推版#include
#include
#include
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<
= 0; u--) { for (int i = 0; i < B; i++) { if ((u&(1<