状态压缩dp,用两位二进制来表示一门课的信息。
code:
#include <iostream>
#include <string>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define clr(a,b) memset((a),b,sizeof(a))
const int maxn = 10010;
typedef long long lld;
const int inf = 0x3f3f3f3f;
int dp[1<<16];
int a[10];
int n,m,s;
int get(int S)
{
int res=0;
for(int i=0;i<s;i++)
{
int tmp=(S>>(2*i))&3;
tmp+=a[i];
if(tmp>=2) tmp=3;
res|=(tmp<<(2*i));
}
return res;
}
int main()
{
while(~scanf("%d %d %d",&s,&m,&n)&&s)
{
int sum=0;
clr(a,0);
clr(dp,inf);
for(int i=0;i<m;i++)
{
int c;
char si;
scanf("%d",&c);
sum+=c;
while(1)
{
char ch=getchar();
if(ch!=' ') break;
int t;
scanf("%d",&t);
a[t-1]++;
}
}
int all=(1<<(s+s))-1;
int S=get(0);
dp[S]=sum;
for(int i=0;i<n;i++)
{
int c;
scanf("%d",&c);
clr(a,0);
while(1)
{
char ch=getchar();
if(ch!=' ') break;
int t;
scanf("%d",&t);
a[t-1]++;
}
for(int j=all;j>=0;j--)
{
if(dp[j]==inf) continue;
S=get(j);
dp[S]=min(dp[S],dp[j]+c);
}
}
printf("%d\n",dp[all]);
}
return 0;
}