\(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;
    }
};