POJ2441 Arrange the Bulls(状压DP)
题目是,有n头牛,每头牛都喜爱某几个草地,要把这n头牛分配给m个不同的它们喜爱的草地,问有几种分配方式。
- dp[n][S]表示前n头牛分配完毕后占用的草地集合是S的方案数
- dp[0][0]=1
- dp[n][S]+=dp[n-1][S-x](x∈S且n喜爱x)
不过的状态这样空间开销太大了,事实上n这个维度的信息S就包含了,所以dp[S]即可。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 int d[1<<20]; 6 bool map[22][22]; 7 int main(){ 8 int n,m,p,a; 9 scanf("%d%d",&n,&m); 10 for(int i=0; i<n; ++i){ 11 scanf("%d",&p); 12 while(p--){ 13 scanf("%d",&a); 14 map[i][a-1]=1; 15 } 16 } 17 int res=0; 18 d[0]=1; 19 for(int i=1; i<(1<<m); ++i){ 20 int cnt=-1; 21 for(int j=0; j<m; ++j){ 22 if((i>>j)&1) ++cnt; 23 } 24 for(int j=0; j<m; ++j){ 25 if(((i>>j)&1) && map[cnt][j]) d[i]+=d[i^(1<<j)]; 26 } 27 if(cnt==n-1) res+=d[i]; 28 } 29 printf("%d",res); 30 return 0; 31 }