zoukankan      html  css  js  c++  java
  • poj1185 [NOI2001]炮兵阵地

    http://poj.org/problem?id=1185

    三维装压dp,压缩上一行状态与本行状态,枚举上两行状态转移

    第一维可以滚掉,实际复杂度只枚举符合情况的情况,每行状态不会超过60并非$2^M$,(然而luogu还是跑T了),证明参见组合数

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    
    const int maxnm = 1001;
    const int maxn = 11;
    int n,m;
    char a[maxn];
    int cant[maxn*10];
    int map[101][11];
    bool check(int x,int i) {
        if(x&cant[i])return false;
        if(x&(x<<1)||x&(x<<2))return false;
        return true;
    }
    int dp[2][1<<maxn][1<<maxn];
    int num[1<<maxn];
    int main( ) {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;++i)  {
            scanf("%s",a) ;
            for(int j=0;j<m;++j)
                if(a[j]=='H')
                cant[i]|=(1<<j);
        }
        int po=(1<<m)-1;
        for(int k,i=1;i<=po;++i) {
            if(!check(i,0))continue;
            k=i;while(k) {
                num[i]+=(k&1);
                k>>=1;
            }
        }
        int ans=-1;
        for(int i=1;i<=n;++i) {
            for(int j=1;j<=po;++j) {
                if(!check(j,i))continue;
                for(int k=1;k<=po;++k) {
                    if(!check(k,i-1)||(k&j)) continue;
                    for(int p=1;p<=po;++p) {
                        if(!check(p,i-2)||(p&j)||(k&p)) continue;
                        dp[i&1][k][j]=std::max(dp[i&1][k][j],dp[(i&1)^1][p][k]+num[j]);
                    }
                    if(i==n)ans=std::max(ans,dp[n&1][k][j]);
                }
            }
        }
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    模板笔记2
    模板笔记
    qt打包可执行文件
    合并单独的视频和音频
    模板1
    mysql 数据表中查找重复记录
    mysql左连接右连接(查询两张表不同的数据)
    mysql--构造数据、导入导出
    mysql安装
    linux下启动tomcat服务
  • 原文地址:https://www.cnblogs.com/sssy/p/8092748.html
Copyright © 2011-2022 走看看