首页 > 代码库 > poj 3254 --- Corn-Fields(状态压缩)
poj 3254 --- Corn-Fields(状态压缩)
- 题意: 一个n*m的矩阵,每个格子是0或者1,0表示土壤肥沃可以种植草地,1则不可以。在种草地的格子可以放牛,但边相邻的两个格子不允许同时放牛,问总共有多少种放牛的方法?(不放牛也算一种情况)
- 我是用两个cheak()函数来判断他是否是可以方牛,然后循环一边就求出了,我是先做了一步预处理,先判断行,如果可以的就把这个数存下,然后每一次从这里面拿出来与上一行进行比较。
- 状态方程就是:i表示第i行,j,k分别表示第i行和j行的状态 dp[i][j]+=dp[i-1][k]
- 源代码:
#include <cstdio> #include <cstring> #include <algorithm> #include <vector> using namespace std; #define mod 100000000 int dp[13][1<<13]; vector<int> mp[20]; int n,m; int a,b[20]; bool cheak2(int x) { return !(x & (x >> 1)); } bool cheak1(int a, int b) { return !(a & b); } int main() { while(scanf("%d%d",&n,&m)==2) { memset(dp,0,sizeof(dp)); for(int i=0; i<n; i++) { b[i]=0; for(int j=0; j<m; j++) { scanf("%d",&a); if(a) b[i]=b[i]|(1<<j); } } for(int i=0;i<n;i++){ // printf("%d\n",b[i]); mp[i].clear(); for(int j=0;j<(1<<m);j++) if(((b[i]|j)==b[i])&&cheak2(j)) mp[i].push_back(j); } /* for(int i=0;i<n;i++){ for(int j=0;j<mp[i].size();j++) { printf("%d ",mp[i][j]); } puts(""); }*/ for(int i=0; i<mp[0].size(); i++) { dp[0][mp[0][i]]=1; } for(int i=1; i<n; i++) for(int j=0; j<mp[i].size(); j++) { for(int k=0;k<mp[i-1].size();k++){ if(cheak1(mp[i][j],mp[i-1][k])) dp[i][mp[i][j]]=(dp[i][mp[i][j]]+dp[i-1][mp[i-1][k]])%mod; } } int ans=0; for(int i=0;i<mp[n-1].size();i++){ ans=(dp[n-1][mp[n-1][i]]+ans)%mod; } printf("%d\n",ans); } } /* 10 10 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 */
poj 3254 --- Corn-Fields(状态压缩)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。