标签:
题目:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=18913
这道题是一道状态压缩DP的好题,有几点要注意的:
1.uva给出的题目不知道为何,题意是有些描述不清的,详见《训练指南》
2.这道题可以有很多写法,整个的dp求解和cover那个部分既可以写成记忆化搜索自顶向下,也可以自底向上来实现。
#include <cstdio> #include <iostream> #include <cstring> using namespace std; /* 状态转移方程: dp[S] = max(dp[S-S‘]+1) if cover(S‘) == ALL */ const int MAXN = 1<<16+5; int a[MAXN], dp[MAXN], C[MAXN]; int ALL; int main () { int n, m, x, kase=1; while(scanf("%d", &n) != EOF && n) { for(int i=0; i<n; i++) { scanf("%d", &m); a[i] = 1<<i; for(int j=0; j<m; j++) { scanf("%d", &x); a[i] |= 1 << x; } } ALL = (1<<n)-1; for(int i=1; i<=ALL; i++) { C[i] = 0; int S = i, cur = 0; while(S) { if(S&1) { C[i] |= a[cur]; } cur++; S>>=1; } } for(int S=1; S<=ALL; S++) { dp[S] = 0; for(int s=S; s; s = (s-1)&S) { // 这里初始 s 可以取到 S if(C[s]==ALL) { dp[S] = max(dp[S^s]+1, dp[S]); } } } printf("Case %d: %d\n", kase++, dp[ALL]); } return 0; }
UVA - 11825 —— Hackers' Crackdown
标签:
原文地址:http://www.cnblogs.com/AcIsFun/p/5296497.html