poj 2441 题意:有N头牛,每头牛都有自己喜欢的barn 而且一个barn只能有一头牛,求给这些牛分配barn 共有多少种方法
#include<bits/stdc++.h> using namespace std; int n,m,x,t; int dp[2][1<<20],a[25][25]; int main(){ scanf("%d%d",&n,&m); memset(a,0,sizeof(a)); memset(dp,0,sizeof(dp)); for(int i = 1;i <= n; ++i){ scanf("%d",&x); while(x--){ scanf("%d",&t); a[i][t] = 1; } } dp[0][0] = 1; for(int i = 1;i <= n; ++i){ for(int j = 0;j < (1 << m); ++j) if(dp[1-i&1][j]){ for(int k = 1;k <= m; ++k){ if(a[i][k] && j != (j|1<<(k-1))){ dp[i&1][j|1<<(k-1)] += dp[1-i&1][j]; } } } memset(dp[1-i&1],0,sizeof(dp[1-i&1])); } int ans = 0; for(int i = 1;i < (1 << m); ++i) ans += dp[n&1][i]; printf("%d\n",ans); return 0; }POJ 2836 题意:农夫有一块地,被划分为m行n列大小相等的格子,其中一些格子是可以放牧的(用1标记),农夫可以在这些格子里放牛,其他格子则不能放牛(用0标记),并且要求不可以使相邻格子都有牛。现在输入数据给出这块地的大小及可否放牧的情况,求该农夫有多少种放牧方案可以选择(注意:任何格子都不放也是一种选择,不要忘记考虑!
#include<bits/stdc++.h> using namespace std; typedef long long ll; ll dp[13][1 << 12]; ll n,m,t; ll b[13],ans; const ll p = 1e9; bool check(ll k){ int x = 0; while(k){ if(k % 2 && x) return 0; x = k % 2; k /= 2; } return 1; } int main(){ scanf("%lld%lld",&n,&m); for(int i = 1;i <= n; ++i){ for(int j = 1; j <= m; ++j){ scanf("%lld",&t); if(!t) b[i] += (1 << (m - j)); } } for(int j = 0;j < (1 << m); ++j) if(check(j) && (j & b[1]) == 0) dp[1][j] = 1; //for(int i = 0;i < (1 << m); ++i) cout<<dp[1][i]<<' '; cout<<endl; for(int i = 2;i <= n; ++i){ ///第i行 for(int j = 0;j < (1 << m); ++j){ if(check(j) && (b[i] & j) == 0){ for(int k = 0;k < (1 << m); ++k){ if(check(k) && (b[i - 1] & k) == 0 && (j & k) == 0){ // cout<<j<<' '<<k<<' '; dp[i][j] = (dp[i][j] + dp[i - 1][k]) % p; // cout<<dp[i][j]<<endl; } } } } } // for(int i =0;i < (1 << m); ++i) cout<<dp[n][i]<<' ';cout<<endl; ans = 0; for(int i = 0;i < (1 << m); ++i) ans = (ans + dp[n][i]) % p; printf("%lld\n",ans); return 0; }