没过,不想写了。。。唉。。。网上找了了代码对拍都拍不出错数据。。。。这泥煤。。。。。。。。。
有大神能帮忙看出来哪里错了就太感谢了。。。。

Code
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int MAXB=21+10,MAXG=8+10;
int c[MAXB][MAXG],res[(1<<21)+10][MAXG],sum[(1<<21)+10],f[(1<<21)+10];
int G,B,S;
int main()
{
freopen("4778.in","r",stdin);
freopen("4778.out","w",stdout);
while(cin>>G>>B>>S){
if((G==0)&&(B==0)&(S==0))break;
memset(c,0,sizeof(c));
for(int i=0;i<B;i++){
int t;cin>>t;
for(int j=0;j<t;j++){
int cj;cin>>cj;
c[i][cj-1]++;
}
}
int MAXS=(1<<B)-1;
memset(sum,0,sizeof(sum));
memset(res,0,sizeof(res));
for(int s=1;s<=MAXS;s++)
for(int i=0;i<G;i++){
for(int j=0;j<B;j++)
if((s>>j)&1)
res[s][i]+=c[j][i];
int d=res[s][i]/S;
res[s][i]-=d*S;
sum[s] +=d;
//cout<<'('<<s<<','<<sum[s]<<')'<<endl;
}
//cout<<"sum"<<sum[MAXS]<<endl;
memset(f,0x80,sizeof(f));f[MAXS]=0;
for(int s=MAXS;s>=0;s--){//s为打开了的背包集合
for(int i=0;i<B;i++)
if((s&(1<<i))){
int x=s^(1<<i),t=(sum[s]-sum[x]);
f[x]=max(((t>0)?(f[s]+t):(-f[s])),f[x]);
//if(s<=1000)cout<<s<<','<<f[s]<<" delta "<<t<<" pre "<<"("<<x<<','<<f[x]<<")"<<endl;
}
//cout<<s<<','<<f[s]<<endl;
}
int ans=f[0];
cout<<ans<<endl;
}
return 0;
}