poj 2441

题意:有N头牛M个棚子,每头牛都有自己喜欢的棚子且每个棚子只能放一头牛,求方案数
Sample in
3 4
2 1 4
2 1 3
2 2 4

Sample out
4

#include <iostream>
#include <cstdio>
#include <iomanip>
#include <string>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <set>
#include <vector>
#include <map>
#include <algorithm>
#include <cmath>
#include <stack>

#define INF 0x3f3f3f3f
#define LINF 0x3f3f3f3f3f3f3f3f
#define ll long long
#define ull unsigned long long
#define uint unsigned int
#define l(x) ((x)<<1)
#define r(x) ((x)<<1|1)
#define lowbit(x) ((x)&(-(x)))
#define abs(x) ((x)>=0?(x):(-(x)))
#define ms(a,b) memset(a,b,sizeof(a))
#define NSYNC std::ios::sync_with_stdio(false);std::cin.tie(0);std::cout.tie(0);

using namespace std;

const int maxn = 2111111;

int dp[(1 << 20) + 5];
int ok[25][25];
int n, m, p, temp;

int main() {
	NSYNC;
	ms(ok, 0);
	ms(dp, 0);
	cin >> n >> m;
	for (int i = 0; i < n; i++) {
		cin >> p;
		for (int j = 0; j < p; j++) {
			cin >> temp;
			ok[i][temp - 1] = 1;
		}
	}

	dp[0] = 1;
	for (int i = 0; i < n; i++) 
		for (int j = (1 << m) - 1; j >= 0; j--) {//从后往前选
			if (dp[j])//没有这行会超时
				for (int k = 0; k < m; k++) 
					if (ok[i][k] && j != (j | (1 << k))) 
						dp[(j | (1 << k))] += dp[j];
			dp[j] = 0;//选完之后把自身重置
		}

	int res = 0;
	for (int i = 0; i < (1 << m); i++) 
		res += dp[i];
	cout << res << "\n";


	return 0;
}


发布了86 篇原创文章 · 获赞 8 · 访问量 2231

猜你喜欢

转载自blog.csdn.net/Fawkess/article/details/103565577
今日推荐