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.
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 c 1 c 2 ... c n
It means that there are n Gems in the bag and their colors are color c 1,color c 2...and color c n 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.
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 c 1 c 2 ... c n
It means that there are n Gems in the bag and their colors are color c 1,color c 2...and color c n 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 -3HintFor 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.
看到数据量很容易想到用状压,但是这样只能求出一方最优的情况,而在这种双方都是最优选择的情况下。往往涉及到博弈论的思想,因为两者是对等的,而且都找最优解。我们就可以将每个状态都设置成当前局面先手的最大得分。当转移时不换人,则保持转移状态。如果转移时换人了,就要把当前值取负再加上增量转移到新的状态,因为另一方选的也是最优解。当然,每个状态都取最大值,因为是最大得分。我们从最终状态开一直转移到最初状态,这样更加容易实现一些。
#include<cstring>
#include<cstdio>
using namespace std;
const int INF=1110000;
int a[22][10],n,m,s,d[(1<<21)+5][10];
//这里有个技巧,对于d[i][j],当j==0时为当前状态的最大值。当j!=0时保存的是当前状态下每种宝石的数量(取模)
//这样做的原因是可以节省转移时临时算各个宝石的时间。
int main()
{
while(~scanf("%d%d%d",&n,&m,&s)&&n+m+s)
{
int ed=1<<m;
memset(a,0,sizeof(a));
memset(d[ed-1],0,sizeof(d[ed-1]));
for(int i=0;i<m;i++)
{
int t,c;
scanf("%d",&t);
for(int j=0;j<t;j++)
{
scanf("%d",&c);
a[i][c]++;
d[ed-1][c]++;
}
}
for(int i=0;i<ed;i++) d[i][0]=-INF;
d[ed-1][0]=0;
for(int i=1;i<=n;i++) d[ed-1][i]%=s;
for(int i=ed-1;i>=0;i--)
{
for(int j=0;j<m;j++)
{
if((i>>j)&1)
{
int sum=0;
int ii=i^(1<<j);
for(int k=1;k<=n;k++)
{
d[ii][k]=d[i][k]-a[j][k];
while(d[ii][k]<0) d[ii][k]+=s,sum++;
}
if(sum==0&&d[ii][0]<-d[i][0]) d[ii][0]=-d[i][0];
if(sum>0&&d[ii][0]<d[i][0]+sum) d[ii][0]=d[i][0]+sum;
}
}
}
printf("%d\n",d[0][0]);
}
}