zoukankan      html  css  js  c++  java
  • 洛谷 P1879 [USACO06NOV]Corn Fields G(状压DP)

    题目链接:https://www.luogu.com.cn/problem/P1879

    这道题有些神奇。

    首先我们把每一行都压缩成一个二进制数,然后我们考虑在某一块土地上是否种草,是否种草则让j从0~maxstate进行枚举。

    只有一种情况是不符合题意的:土地为0,而种草为1。那么即(j&f[i]!=j)就为这种情况。

    根据1&1=1,0&1=0,1&0=0,0&0=0。
    设x&y=z,那么我们可以发现一个规律,只有当x=0,y=1时,y不等于z。
    即可以证明(j&f[i]))!=j的正确性。
    解释

    其他的就按一个基本的状压DP来即可。

    dp[][]:第一维为行数,第二维为状态。

    AC代码:

     1 #include<cstdio>
     2 #include<iostream>
     3 using namespace std;
     4 typedef long long ll;
     5 const ll mod=1e9;
     6 ll dp[20][4100];
     7 int f[4100];
     8 int state[4100];
     9 int main(){
    10     int m,n;
    11     scanf("%d%d",&m,&n);
    12     int maxstate=(1<<n);
    13     for(int i=1;i<=m;i++){
    14         for(int j=1;j<=n;j++){
    15             int x;
    16             scanf("%d",&x);
    17             f[i]=(f[i]<<1)+x;
    18         }
    19     }
    20     for(int i=0;i<maxstate;i++) state[i]=((i&(i<<1))==0&&(i&(i>>1))==0);
    21     dp[0][0]=1;
    22     for(int i=1;i<=m;i++){
    23         for(int j=0;j<maxstate;j++){
    24             if(state[j]==0||((j&f[i]))!=j) continue;//太神奇了 
    25             for(int k=0;k<maxstate;k++) if((j&k)==0) dp[i][j]=(dp[i][j]+dp[i-1][k])%mod;
    26         }
    27     }
    28     ll ans=0;
    29     for(int i=0;i<maxstate;i++){
    30         ans+=dp[m][i];
    31         ans%=mod;
    32     }
    33     printf("%lld
    ",ans);
    34     return 0;
    35 }
    AC代码
  • 相关阅读:
    物理数据库设计
    物理数据库设计
    NHibernate 帮助类(单例实际运用)
    HttpContext请求上下文对象
    SqlDataReader类
    在你不懂怎么做的时候
    System.Object 基类
    逻辑数据库设计
    逻辑数据库设计
    NHibernate使用MemCache二级缓存
  • 原文地址:https://www.cnblogs.com/New-ljx/p/12493571.html
Copyright © 2011-2022 走看看