zoukankan      html  css  js  c++  java
  • 洛谷 P2704 [NOI2001]炮兵阵地(状压DP)

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

    压两行的状压DP。

    预处理:将H为1,P为0;在某个点放炮兵为1,不放为0。很显然只有_&_=1时,是不合法的。

    首先枚举(1<<m)-1个状态,只将行上没有冲突的状态记录下来,并记录当前行上炮兵的个数,否则会re。

    然后处理第一行:如果状态state[i]&mp[1]==0,说明它是合法的,那么dp[1][1][i]=sum[i]。

    注意这里,state[1]必然等于0,那么对于第一行,只有0是不会影响第一行状态的,所以它的上一行状态编号为1。

    最后每一行处理:枚举上上行、上行和这一行,判断上下三行中是否有炮兵在同一列上,以及这一行上想要放炮兵的位置是否为H,如果有其一,则不合法。

    然后暴力转移:dp[i][k][l]=max(dp[i][k][l],dp[i-1][j][k]+sum[l]);

    最后ans=max{dp[n][][]},后两维枚举状态。

    dp[i][j][k]:[第i行]   [第i行状态编号]   [第i-1行状态编号]

    -->此状态下炮兵总个数。

    AC代码:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 using namespace std;
     5 int dp[110][70][70],state[110],sum[110],mp[110],tot;
     6 int cul(int x){
     7     int cnt=0;
     8     while(x){
     9         if(x&1) cnt++;
    10         x>>=1;
    11     }
    12     return cnt;
    13 }
    14 int main(){
    15     int n,m;
    16     scanf("%d%d",&n,&m);
    17     for(int i=1;i<=n;i++)
    18     for(int j=0;j<m;j++){//注意从0开始
    19         char ch=getchar();
    20         while(ch!='H'&&ch!='P') ch=getchar();
    21         if(ch=='H') mp[i]|=(1<<j);//第j位赋值1
    22     }
    23     for(int i=0;i<(1<<m);i++)
    24         if((i&(i<<1))==0&&(i&(i<<2))==0) state[++tot]=i,sum[tot]=cul(i);
    25     for(int i=1;i<=tot;i++) if((state[i]&mp[1])==0) dp[1][1][i]=sum[i];//注意这里的处理
    26     for(int i=2;i<=n;i++)
    27     for(int j=1;j<=tot;j++)
    28     for(int k=1;k<=tot;k++){
    29         if((state[j]&state[k])||dp[i-1][j][k]==0) continue;
    30         for(int l=1;l<=tot;l++){
    31             if((state[l]&state[k])||(state[l]&state[j])||(state[l]&mp[i])) continue;
    32             dp[i][k][l]=max(dp[i][k][l],dp[i-1][j][k]+sum[l]);
    33         }
    34     }
    35     int ans=0;
    36     for(int i=1;i<=tot;i++)
    37     for(int j=1;j<=tot;j++)
    38     ans=max(dp[n][i][j],ans);
    39     printf("%d
    ",ans);
    40     return 0;
    41 }
    AC代码
  • 相关阅读:
    关于Debian中virtualbox的问题
    aptget和aptitude的区别
    Archlinux安装笔记
    数组全排列的递归方法实现
    Debian卸载iceweasel
    一起学WP7 XNA游戏开发(八. 让3d model动起来)
    一起学windows phone7开发(二十五.Toolkit 增补)
    专业windows phone7开发网站上线
    《一起学Windows phone7开发》系列视频课程
    一起学WindowsPhone7开发(二十六. Advertising)
  • 原文地址:https://www.cnblogs.com/New-ljx/p/12519469.html
Copyright © 2011-2022 走看看