zoukankan      html  css  js  c++  java
  • [POJ 1185] 炮兵阵地

    Link:

    POJ 1185 传送门

    Solution:

    看大家都说是一道状压$dp$基础题,结果我还是卡题了

    发现决策第$i$行时,要同时考虑$i-1$和$i-2$行,因此状态中要包含两个“行”状态位

    但$O(1024^3*100)$的复杂度明显不行啊,于是我就在这卡住了……

    其实可以发现仅考虑“行合法”的行状态与前后行无关,可以预处理,而且只有不到70种!

    于是将原来的$1024$种行状态缩减为已保证“行合法”的$70$中状态即可

    这里对每行集体判断和 [BZOJ 2734] 集合取数  中 求表格上任意两点不相邻的点集数 的判断方式类似

    用 !(st[l]&st[j]) 和 !(st[l]&st[k]) 判断与上两行的列是否有冲突

    同时将原来输入的'N'、'P',转换为'1'、'0',判断位与是否不为0

    Code:

    #include <iostream>
    #include <cstdlib>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    
    using namespace std;
    
    const int MAXN=110,MST=70;
    int n,m,dp[MAXN][MST][MST],dat[MAXN],sum[MST],st[MST],tot=0,res=0;
    
    int cal(int x) //计算其中1的个数
    {
        int ret=0;
        while(x) ret+=(x&1),x>>=1;
        return ret;
    }
    
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) for(int j=0;j<m;j++)
        {
            char ch=getchar();
            while(ch!='P' && ch!='H') ch=getchar();
            if(ch=='H') dat[i]|=(1<<j);
        }
        for(int i=0;i<(1<<m);i++) //预处理出一行可能的状态 
            if(!(i&(i<<1)) && !(i&(i<<2))) st[++tot]=i,sum[tot]=cal(i);
        
        for(int i=1;i<=tot;i++)
            if(!(st[i]&dat[1])) dp[1][1][i]=sum[i];
        for(int i=1;i<n;i++)
            for(int j=1;j<=tot;j++)
                for(int k=1;k<=tot;k++)
                    if(!(st[j]&st[k]) && dp[i][j][k])
                        for(int l=1;l<=tot;l++) //通过位移和位与集体判断
                            if(!(st[l]&st[j]) && !(st[l]&st[k]) && !(st[l]&dat[i+1]))
                                dp[i+1][k][l]=max(dp[i+1][k][l],dp[i][j][k]+sum[l]);
        
        for(int i=1;i<=tot;i++) 
            for(int j=1;j<=tot;j++)
                res=max(res,dp[n][i][j]);
        printf("%d",res);
        return 0;
    }

    Review:

    (1)查看有没有可以事先预处理出的合法的状态来对总数缩减

    (2)利用 移位 + 位与 的方式对“行状态”整体判断算是常用套路了吧

  • 相关阅读:
    Android 架构 1.架构
    Android UI 统一修改Button控件的样式,以及其它系统控件的默认样式
    RobotFrameWork+APPIUM实现对安卓APK的自动化测试----第三篇【实例】
    RobotFrameWork+APPIUM实现对安卓APK的自动化测试----第二篇【原理】
    RobotFrameWork+APPIUM实现对安卓APK的自动化测试----第一篇【安装】
    选择日期控件
    robot Framework控制浏览器
    botot framework选择下拉框
    soapui测试接口使用步骤
    使用python实现appium的屏幕滑动
  • 原文地址:https://www.cnblogs.com/newera/p/9157614.html
Copyright © 2011-2022 走看看