• POJ1185 炮兵阵地(状压dp)


    传送门

    解题思路:

      恒定两格的范围,那么对于每个坐标(i,j)只需要考虑(i-1,j)、(i-2,j)、(i,j-1)、(i,j-2)四种情况,很自然的可以想到以行作为状态转移的阶段,设dp[i][j][k]表示第i行的状态压缩为j,第i-1行状态压缩为k,设cnt[j]为状态压缩为j的情况下1的个数。那么转移方程为

      dp[i][j][k]=max(dp[i][j][k],dp[i-1][k][h]+cnt[j])

      很明显这要枚举i、j、k、h,时间复杂度为o(n*2^(3*m))

      但是这里面存在着大量的冗余,一个状态集合中的两个1距离要大于2,那么预处理完会发现常数极小,2^10预处理完只剩60个(细品),其实还可以预处理状态j有多少个满足条件的k(可以搞但没必要~~)。再一次验证了dp就是去除大量冗余运算用空间换取时间的搜索

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    int num[1001],tot;
    char s[105][15];
    int dp[105][105][105];
    int main()
    {
        int n,m;scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)    scanf("%s",s[i]);
        for(int i=0;i<(1<<m);i++){
            bool flag=true;
            for(int j=1;j<m;j++){
                if((j>1&&(i&(1<<j))&&(i&(1<<(j-2))))||((i&(1<<j))&&(i&(1<<(j-1))))){
                    flag=false;break;
                }
            }
            if(flag)    num[tot++]=i;
        }
        memset(dp,-0x3f,sizeof dp);dp[0][0][0]=0;int ans=0;
        for(int i=1;i<=n;i++){
            for(int j=0;j<tot;j++){
                for(int h=0;h<tot;h++){
                    if(dp[i-1][j][h]<0)    continue;
                    for(int k=0;k<tot;k++){
                        int t1=num[j],t2=num[h],t3=num[k];bool flag=true;int cnt=0,c=0;
                        for(int p=0;p<10;p++){
                            if((s[i][p]=='H'&&(t3&(1<<p)))||((t3&(1<<p))&&((t1&(1<<p))||(t2&(1<<p))))){
                                flag=false;break;
                            }
                            if(t3&(1<<p))    cnt++;
                        }
                        if(flag)
                            dp[i][k][j]=max(dp[i][k][j],dp[i-1][j][h]+cnt),ans=max(ans,dp[i][k][j]);
                    }
                }
            }
        }
        cout<<ans<<endl;
    }
    View Code

      

  • 相关阅读:
    PV、UV、VV、IP是什么意思?
    多用户远程linux
    实用性阅读指南读书笔记
    在VS添加万能头文件 操作
    sqrt函数实现之卡马克方法
    大端法、小端法及其判断方法
    STL源码剖析之ROUND_UP函数实现原理及其拓展
    海康和多益面经
    小米实习生面试面经
    阿里c++一面面经
  • 原文地址:https://www.cnblogs.com/r138155/p/12652092.html
Copyright © 2020-2023  润新知