Topcoder9902 SRM416 DancingCouples

\(dp[i][S]\)表示选到某个男生,女生的选择集合。然后暴力转移,复杂度\(O(2^{n*m}*K*m)\)

极限数据一亿多,然而卡过去了。

#include<bits/stdc++.h>
#define clr(x,y) memset(x,y,sizeof(x))
using namespace std;
int n,m,ans=0;
bool A[15][15];
vector<int>P; 
int dp[15][1<<10];//选到某个男生,女生的选择情况,方案数 
int calc(int x){
	int ct=0;
	while(x)x-=(x&-x),ct++;
	return ct;	
}
class DancingCouples {
public:
	int countPairs(vector <string> canDance, int K) {
		ans=0;
		n=canDance.size();
		m=canDance[0].size();
		for(int i=0;i<n;i++)
			for(int j=0;j<m;j++)
				A[i][j]=(canDance[i][j]=='Y');
		for(int i=0;i<1<<n;i++){//状压选择的男生 
			if(calc(i)!=K)continue;
			P.clear();
			for(int j=0;j<n;j++)
				if(i&1<<j)P.push_back(j);
			dp[0][0]=1;
			for(int j=0;j<K;j++){
				int x=P[j];
				clr(dp[j+1],0);
				for(int k=0;k<1<<m;k++){
					for(int r=0;r<m;r++){
						if(k&1<<r)continue;
						if(A[x][r])dp[j+1][k|(1<<r)]+=dp[j][k];		
					}
				}
			}
			for(int j=0;j<1<<m;j++)
				ans+=dp[K][j]; 
		}
		return ans;
	}
};
posted @ 2019-02-16 16:22  zeroy0410  阅读(109)  评论(0编辑  收藏  举报