zoukankan      html  css  js  c++  java
  • <USACO06NOV>玉米田Corn Fields

    状压emm

    二进制真有趣

    来自dp垃圾的欣喜

    Description

    • 农民 John 购买了一处肥沃的矩形牧场,分成M*N(1 <= M <= 12; 1 <= N <= 12)个格子。他想在那里的一些格子中种植美味的玉米。遗憾的是,有些格子区域的土地是贫瘠的,不能耕种。精明的 FJ 知道奶牛们进食时不喜欢和别的牛相邻,所以一旦在一个格子中种植玉米,那么他就不会在相邻的格子中种植,即没有两个被选中的格子拥有公共边。他还没有最终确定哪些格子要选择种植玉米。作为一个思想开明的人,农民 John 希望考虑所有可行的选择格子种植方案。由于太开明,他还考虑一个格子都不选择的种植方案!请帮助农民 John 确定种植方案总数。

    Input

    • Line 1: 两个用空格分隔的整数 M 和 N
    • Lines 2M+1: 第 i+1 行描述牧场第i行每个格子的情况, N 个用空格分隔的整数,表示 这个格子是否可以种植(1 表示肥沃的、适合种植,0 表示贫瘠的、不可种植)

    Output

    • Line 1: 一个整数: FJ 可选择的方案总数 除以 100,000,000 的余数。

     

    Sample Input

    • 2 3

             1  1  1

             0  1  0

    Sample Output

    • 9

    Hint

    • 【样例说明】

         给可以种植玉米的格子编号:
                          1 2 3
                           4
         只种一个格子的方案有四种 (1, 2, 3, 或 4),种植两个格子的方案有三种 (13, 14, 或 34),种植三个格子的方案有一种 (134),还有      一种什么格子都不种。 4+3+1+1=9。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    const int N=100000000;
    int m,n;
    int dp[15][8000],field[15][15],judge[8000],f[15];
    
    int main()
    {
        int i,j,k,maxx;
        //freopen("cowfood.in","r",stdin); 
        //freopen("cowfood.out","w",stdout);
        scanf("%d%d",&m,&n);
        for(i=1;i<=m;i++)
            for(j=1;j<=n;j++)scanf("%d",&field[i][j]);
        for(i=1;i<=m;i++)
            for(j=1;j<=n;j++)f[i]=(f[i]<<1)+field[i][j];//注意.f[i]里表示一行的0101010的分布情况!!所以 左移一位加上field(里面是0或1)就可以啦!!!
        maxx=1<<n;//表示一行n个0(最前面的1不会用到w ..这个自行意会 感觉这样说不对.. 
        for(i=0;i<maxx;i++) judge[i]=((i&(i<<1))==0) && ((i&(i>>1))==0);//看清括号quq左移右移判断 如果 返回都为0 说明满足条件 即不同时为1 //返回均为0时,judge为1 
        dp[0][0]=1;
        for(i=1;i<=m;i++)
            for(j=0;j<maxx;j++)//二进制的 一行的可能方式枚举 
                if(judge[j] && ((j&f[i])==j))//当之前的判断满足.想一想..f[i]要怎样满足条件..???emm..
                {                           // 就..随便列个式子写下 会发现.!对应要为1时 f[i] 也要为1 而j该位为0时 f[i]为0or1都可以.! 
                    for(k=0;k<maxx;k++) if((k&j)==0) dp[i][j]=(dp[i][j]+dp[i-1][k])%N;//当 k和j没有1相邻时..即可以是在在一起的两列时,dp[i][j]加上前一行&列也就是这个dp[i-1][k]emm就是这时的方案数啦             
                } 
        int ans=0;
        for(i=0;i<=maxx;i++)ans+=dp[m][i],ans%=N;
        printf("%d
    ",ans); 
         
    return 0;
    }
  • 相关阅读:
    IntelliJ IDEA 2020.1.1中java web项目的配置
    Js查漏补缺10-数组、栈、队列、回调函数等
    Js查漏补缺09-this对象
    Js查漏补缺08-闭包
    Js查漏补缺07-匿名函数应用到的框架
    Js查漏补缺06-匿名函数的用法
    Js查漏补缺05-函数
    Js查漏补缺04-Object类型
    Js查漏补缺03-循环结构
    Runnabler
  • 原文地址:https://www.cnblogs.com/pile8852/p/9286241.html
Copyright © 2011-2022 走看看