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

    传送门


    解题思路

    用dp[h][i][j]表示处理到第h行,这一行状态是i,上一行状态是j的最大数量。

    枚举第几行、这一行的状态、上一行的状态、上上行的状态,判断转移即可。

    注意要用滚动数组(只会用到上一行、上上行)。

    AC代码

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cmath>
     4 #include<cstdio>
     5 #include<cstring>
     6 using namespace std;
     7 int n,m,a[105],dp[3][1100][1100],ans; 
     8 int work(int x){
     9     int ans=0;
    10     while(x>0){
    11         ans+=x&1;
    12         x>>=1;
    13     }
    14     return ans;
    15 }
    16 int main()
    17 {
    18     cin>>n>>m;
    19     for(int i=1;i<=n;i++){
    20         for(int j=1;j<=m;j++){
    21             char c;
    22             cin>>c;
    23             a[i]<<=1;
    24             if(c=='H') a[i]|=1; 
    25         }
    26     }
    27     for(int i=0;i<=(1<<m)-1;i++){
    28         if(i&a[1]) continue;
    29         if(i&(i<<1)||i&(i<<2)) continue;
    30         dp[1][i][0]=work(i);
    31     }
    32     for(int i=0;i<=(1<<m)-1;i++){
    33         if(i&a[2]) continue;
    34         if(i&(i<<1)||i&(i<<2)) continue;
    35         int num=work(i);
    36         for(int j=0;j<=(1<<m)-1;j++){
    37             if(j&a[1]) continue;
    38             if((j&(j<<1))||(j&(j<<2))||(i&j)) continue;
    39             dp[2][i][j]=max(dp[2][i][j],dp[1][j][0]+num);
    40         }
    41     }
    42     for(int h=3;h<=n;h++){
    43         for(int i=0;i<=(1<<m)-1;i++){
    44             if(i&a[h]) continue;
    45             if(i&(i<<1)||i&(i<<2)) continue;
    46             int num=work(i);
    47             for(int j=0;j<=(1<<m)-1;j++){
    48                 if(j&a[h-1]) continue;
    49                 if((j&(j<<1))||(j&(j<<2))||(i&j)) continue;
    50                 for(int k=0;k<=(1<<m)-1;k++){
    51                     if(k&a[h-2]) continue;
    52                     if((i&k)||(j&k)||(k&(k<<1))||(k&(k<<2))) continue;
    53                     dp[h%3][i][j]=max(dp[h%3][i][j],dp[(h-1)%3][j][k]+num);
    54                 }
    55             }
    56         }
    57     }
    58     for(int i=0;i<=(1<<m)-1;i++){
    59         for(int j=0;j<=(1<<m)-1;j++){
    60             ans=max(ans,dp[n%3][i][j]);
    61         }
    62     }
    63     cout<<ans;
    64     return 0;
    65 }
  • 相关阅读:
    为什么 Redis 重启后没有正确恢复之前的内存数据
    Redis的启动过程
    Redis 如何保持和MySQL数据一致
    redis集群节点宕机
    mysql 数据库管理
    mysqladmin 命令详解
    MySQL 编译安装
    mysql 数据库简介
    xtrabackup安装部署(二)
    Non-negative Partial Sums(单调队列)
  • 原文地址:https://www.cnblogs.com/yinyuqin/p/14040061.html
Copyright © 2011-2022 走看看