子集的枚举: “ for(int s = mask ; s ; s = (mask&(s-1))) ” 不过可别忘了这里枚举到s就退出了,所以要把s为0的情况补上。 当然也可以用记忆化方法递归求解~~~ 有时间补上。 #include <cstdio> #include <cstring> #include <algorithm> #include <map> #define max(a, b) (a > b ? a : b) using namespace std; int dp[65536]; int main(int argc, char* argv[]) { int n, m; while(scanf("%d %d", &n, &m) != EOF) { int max = (1<<n)-1; memset(dp, 0, sizeof(dp)); for(int i = 0; i < m; i++) { int k; scanf("%d", &k); int t, pf = 0; for(int j = 0; j < k; j++) { scanf("%d", &t); pf |= (1<<(t-1)); } dp[pf] = max(1, dp[pf]); //由于下面子集枚举的循环中,到0时就退出了。所以在这里补上。 int mask = max^pf; for(int s = mask ; s ; s = (mask&(s-1))) { dp[s|pf] = max(dp[s|pf], dp[s]+1); } //当然这段代码也可以这么写 //for(int s = mask ; ; s = (mask&(s-1))) { // dp[s|pf] = max(dp[s|pf], dp[s]+1); // if(s == 0) { // break; // } //} } printf("%d/n", dp[max]); } return 0; }