2441:Arrange the Bulls
問題文
http://poj.org/problem?id=2441
n頭の牛がいて、m棟の小屋がある。牛にはそれぞれ入れる小屋が決まっていて、全部の牛を小屋に入れるような入れ方が何通りあるかを求めよ。
ビットDPした。
dp[ 牛の番号 ][ どの小屋を使ったか ] := 場合の数
配列がとれなかったので遇奇で使い回した。
コード中のjとSのループを回す順番を逆にするとTLEする。
#include<iostream> #include<vector> #include<algorithm> #include<cstdio> using namespace std; int dp[2][1<<20],cow[21][21],p[21]; int main(void){ int n,m; scanf("%d %d",&n,&m); for(int i=1;i<=n;i++){ scanf("%d",&p[i]); for(int j=0;j<p[i];j++)scanf("%d",&cow[i][j]); } dp[0][0]=1; for(int i=1;i<=n;i++){ for(int j=0;j<p[i];j++){ for(int S=0;S<(1<<m);S++){ if(S>>(cow[i][j]-1)&1)dp[i&1][S]+=dp[(i-1)&1][S&~(1<<(cow[i][j]-1))]; } } for(int j=0;j<(1<<m);j++)dp[(i-1)&1][j]=0; } int ans=0; for(int i=0;i<(1<<m);i++)ans+=dp[n&1][i]; cout << ans << endl; return 0; }