Description
小学的时候,Stubird非常喜欢玩游戏王,有一天,他发现了一个绝佳的连锁组合,这个连锁组合需要6张卡, 可是他一张都没有,但是他的那些朋友们有,不过当然,他们不会白给,不过也不排除有人和他交情好,送给他了。 不过他们有成全别人的美德,当他们看到Stubird已经有某些他们喜欢的卡的时候,他们会给他优惠,或者更贵也说不定 嘛不过,你可以把有的卡片藏起来,不告诉他们,来获得更低的价格。 问他最少需要多少钱才可以集齐所有的卡。
Input
第一行T,表示有T个测试样例 第二行,n表示他有n个朋友(n<=100) 下一行,m(0<=m<=2的6次方)表示有多少种卡片的集合,num表示他有的这张卡片的编号是(0-5),数据保证所给的集合不重复; 3*m行,第一行都有一个数,k(k<=5),表示这个集合包含的卡片张数 下一行k个数,表示每张卡片的编号(0-5)(不会包含num) 下一行一个数c,表示如果你有这个组合下购买num卡,所需要的花费c;
Output
输出最小的花费,如果不可能集齐则输出-1
Sample Input
1 6 1 0 0 1 1 1 0 1 1 2 0 1 1 3 0 1 1 4 0 1 1 5 0 1
Sample Output
6
HINT
大意:呃....没有大意- -题解说是状态DP,反正还没学到,bin神代码先挂着~~
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
/* *********************************************** Author :kuangbin Created Time :2015/3/15 14:17:30 File Name :GDUT\A.cpp ************************************************ */ #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <set> #include <map> #include <string> #include <math.h> #include <stdlib.h> #include <time.h> using namespace std; const int INF = 0x3f3f3f3f; int dp[1000]; int st[6410],cost[6410]; int num[6410]; int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int T; scanf("%d",&T); while(T--){ int n; scanf("%d",&n); int cnt = 0; for(int i = 0;i < n;i++){ int m; int nn; int p; scanf("%d%d",&m,&nn); while(m--){ int k; scanf("%d",&k); st[cnt] = 0; num[cnt] = nn; while(k--){ scanf("%d",&p); st[cnt] |= (1<<p); } scanf("%d",&cost[cnt]); cnt++; } } for(int i = 0;i < (1<<6);i++)dp[i] = INF; dp[0] = 0; for(int i = 0;i < (1<<6);i++){ if(dp[i] == INF)continue; for(int j = 0;j < cnt;j++){ if( (i&(1<<num[j])) != 0)continue; if( (i|st[j]) != i )continue; dp[i|(1<<num[j])] = min(dp[i|(1<<num[j])],dp[i]+cost[j]); } } int tot = (1<<6)-1; if(dp[tot] == INF)dp[tot] = -1; printf("%d\n",dp[tot]); } return 0; }