ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

P1879 [USACO06NOV]Corn Fields G(状压dp)

2020-09-22 20:31:31  阅读:277  来源: 互联网

标签:ch int Fields Corn 状压 土地 John mp include


题目链接

 

 

f[i][j]表示前[i]行的状态为j时的合法方案数

mp[i]刻画的是土地

possi[i]判断是否合法

步骤:

1.读进来土地,把它二进制转十进制

2.判断草地是否相邻,即是否有连续的1。(i与他的左移一位和右移一位,分别做&运算,如果都都等于0,那么合法)举个例子:

比如说 6→110 (有连续的两个1,是个不合法的)

 1 1 0                 1 1 0

& 0 1 1                 1 0 1

得:0 1 0(×)            1 0 0(×)

3.再枚举每行可能状态,判断是否有种在贫瘠土地上的情况。什么叫种在贫瘠土地上呢?就是原本土地(i,j)这个格子上是个0,你却冒出来个1,就是不行的。这有两种判断合法的方式:(j&mp[i])==j和(j|mp[i])==mp[i]。仍然举个例子

 

j       0 1 0                        0 1 0

mp   0 0 1                        0 0 1

&得  0 0 0 (×)     |得: 0 1 1(×)

 

 

 

 

 

农场主John新买了一块长方形的新牧场,这块牧场被划分成M行N列(1 ≤ M ≤ 12; 1 ≤ N ≤ 12),每一格都是一块正方形的土地。John打算在牧场上的某几格里种上美味的草,供他的奶牛们享用。

遗憾的是,有些土地相当贫瘠,不能用来种草。并且,奶牛们喜欢独占一块草地的感觉,于是John不会选择两块相邻的土地,也就是说,没有哪两块草地有公共边。

John想知道,如果不考虑草地的总块数,那么,一共有多少种种植方案可供他选择?(当然,把新牧场完全荒废也是一种方案)

输入格式

第一行:两个整数M和N,用空格隔开。

第2到第M+1行:每行包含N个用空格隔开的整数,描述了每块土地的状态。第i+1行描述了第i行的土地,所有整数均为0或1,是1的话,表示这块土地足够肥沃,0则表示这块土地不适合种草。

输出格式

一个整数,即牧场分配总方案数除以100,000,000的余数。

输入输出样例

输入 #1
2 3
1 1 1
0 1 0
输出 #1
9

 

 

#include<cstring>
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
template <typename Tp>
void read(Tp &x){//read(n);
    x=0;char ch=1;int fh;
    while(ch!='-'&&(ch>'9'||ch<'0')){
        ch=getchar();
    }
    if(ch=='-'){
        fh=-1;ch=getchar();
    }else fh=1;
    while(ch>='0'&&ch<='9'){
        x=(x<<1)+(x<<3)+ch-'0';ch=getchar();
    }
    x*=fh;
}
inline char read1()//字符串读入挂
{
    register char ch=getchar();
    while(ch<'A'||ch>'M')ch=getchar();
    return ch;
}
const int maxn=1e6+100;
const int mod=100000000;
ll n,m,ans;
ll f[13][1<<13];
ll g[1<<12],h[1<<12],a[13][13];
ll v[13];
int main(){
    int x;
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cin>>x;
            v[i]=(v[i]<<1)+x;
        }
    }
    f[0][0]=1;
    for(int i=0;i<(1<<m);i++){
        if(!(i&(i<<1))&&!(i&(i>>1))){//判断是否该列合法,即没有连续的1 
            g[i]=1;
        }
    }
    for(int i=1;i<=n;i++){//枚举每行 
        for(int j=0;j<(1<<m);j++){//枚举可能的状态 
            if(g[j]&&(j&v[i])==j){//判断状态是否合法(没有相邻的1)且没有种在贫瘠的土地上 
                for(int k=0;k<(1<<m);k++){//找上一个合法的状态 
                    if(!(k&j)){//与该行的状态取&不为真(0)
                    //说明上一行和这一行不存在任意一行草地有公共边 
                        f[i][j]=(f[i][j]+f[i-1][k])%mod;//记录 
                    }
                }
            }
        }
    }
    for(int i=0;i<(1<<m);i++){
        ans=(ans+f[n][i])%mod;
    }
    cout<<ans<<endl;
}

 

标签:ch,int,Fields,Corn,状压,土地,John,mp,include
来源: https://www.cnblogs.com/lipu123/p/13714715.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有