zoukankan      html  css  js  c++  java
  • poj 3254 Corn Fields

    题意:给一个n*m的图,图上点有两种状态,0和1,1表示可以标记,0不可以,如果一个点标记之后,他的上下左右都不可以标记,求所有的可能的情况

    分析:n,m<=12,我们可以想到用二进制表示每个点的状态,是否标记,那么dp[i][j]=sum(dp[i-1][k]),i表示行,j表示状态,比如5,二进制位101,表示1,3标记,其他的点不标记

    我开了两个vector保存上一次的所有符合要求的枚举量和记录这次的枚举量,这样枚举上一行的时候不需要再枚举所有的可能量,但是vector速度比较慢,效果并不好

    16ms过的,如果用数组模拟vector,会快很多,动手强的自己搞一下

    #include<cstdio>
    #include<cstring>
    #include<vector>
    #include<iostream>
    using namespace std;
    const int maxn=13;
    const int mod=1e8;
    
    int sn,map[maxn][maxn],state[1<<maxn],dp[2][1<<maxn];
    int n,m;
    void cal(){
        sn=0;
        for(int i=0;i<(1<<m);i++)
          if(!(i&(i<<1)))
            state[sn++]=i;
    }
    
    //判断状态j在第i行是否可行
    bool judge(int i,int j){
        for(int k=0;k<m;k++)
          if(!map[i][k]&&(state[j]&(1<<k)))
            return false;
        return true;
    }
    
    
    int main(){
        scanf("%d%d",&n,&m);
        cal();
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=n;i++)
          for(int j=0;j<m;j++)
            scanf("%d",&map[i][j]);
        vector<int> d[2];//保存上一行的正确状态,减少枚举量,也可以用滑动数组实现
        d[0].push_back(0);
        dp[0][0]=1;
        for(int i=1;i<=n;i++){
            int p=(i-1)%2;
            d[i%2].clear();
            for(int j=0;j<sn;j++){
                dp[i%2][state[j]]=0;
                if(!judge(i,j))continue;
                for(int k=0;k<d[p].size();k++)
                  if(state[j]&d[p][k])
                    continue;
                  else{
                    dp[i%2][state[j]]+=dp[p][d[p][k]];
                    dp[i%2][state[j]]%=mod;
                  }
                if(dp[i%2][state[j]])
                d[i%2].push_back(state[j]);
            }
        }
        int ans=0,p=n%2;
        for(int i=0;i<d[p].size();i++){
            ans+=dp[p][d[p][i]];
            ans%=mod;
        }
    
        printf("%d
    ",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    jvm的概述
    关于请求中的一些小知识点
    对react项目进行进一步的修饰
    java基于token进行登录超时检验和有效性校验
    react获取文本框的值
    redis数据库的缓存击穿和缓存穿透
    centos克隆虚拟机
    Java中的第三大特性-多态性
    java中String类的使用
    Maven更换阿里源与仓库地址
  • 原文地址:https://www.cnblogs.com/jihe/p/5238038.html
Copyright © 2011-2022 走看看