很经典的一道状态压缩DP~

刚开始写这道题目的时候分析了下,很明显的二进制压缩,每行有1024中情况,但是每两个阵地之间至少要相隔2,最后一算只有60种形态。

感觉不是很麻烦就写了,写着发现不对劲,由于一行需要由前面两行的状态决定,而我开的是二维数组,怎么也不能完全的把信息转换过来。。

一直很纠结于怎样传递信息,最后很无奈的上网搜了下代码,发现用三维的数组就可以了。。

DP[i][j][k]表示第i行当前为第j种状态,i-1行为第k种状态,那么状态转移方程就很容易搞定了。。

DP[i][j][k]=max(DP[i][j][k],DP[i-1][k][h]),其中(st[j]&st[k])==0,(st[j]&st[h])==0,(st[k]&st[h])==0.

st[j]表示第j种状态。

贴下代码:(很龊的)

View Code

  1 # include<stdio.h>  2 # include<string.h>  3 int n,m;  4 int s[11]={1,2,4,8,16,32,64,128,256,512,1024};  5 char map[105][12];  6 int DP[102][65][65];  7 int st[65];  8 int judge(int i)//判断状态i是否符合要求  9 { 10     int end,cur,ans; 11     end=-3; 12     cur=-1; 13     while(i) 14     { 15         cur++; 16         ans=i%2; 17         if(ans==1) 18         { 19             if(cur-end<3) 20             return 0; 21             end=cur; 22         } 23         i/=2; 24     } 25     return 1; 26 } 27 int cmp(int i)//求i的二进制中有多少个1 28 { 29     int count=0; 30     while(i) 31     { 32         if(i%2) count++; 33         i/=2; 34     } 35     return count; 36 } 37 int max(int a,int b) 38 { 39     return a>b?a:b; 40 } 41 int main() 42 { 43     int i,j,k,h,i1,ans,temp; 44     k=0; 45     for(i=0;i<1024;i++) 46     { 47         if(judge(i)) st[k++]=i; 48     } 49     while(scanf("%d%d",&n,&m)!=EOF) 50     { 51         for(i=0;i<n;i++) 52             scanf("%s",map[i]); 53         memset(DP,0,sizeof(DP)); 54         ans=0; 55         temp=0; 56         for(i=0;i<m;i++) 57             if(map[0][i]=='H') temp+=s[i]; 58         for(i=0;i<k;i++) 59         { 60             if(st[i]>=s[m]) break; 61             /*for(j=0;j<m;j++) 62                 if((st[i]&s[j]) && map[0][j]=='H') break; 63             if(j<m) continue;*/ 64             if(st[i]&temp) continue; 65             for(j=0;j<k;j++) 66             { 67                 if(st[j]>=s[m]) break; 68                 DP[0][i][j]=cmp(st[i]); 69             } 70             ans=max(ans,DP[0][i][0]); 71         } 72         for(i=1;i<n;i++) 73         { 74             for(j=0;j<k;j++) 75             { 76                 if(st[j]>=s[m]) break; 77                 temp=0; 78                 for(h=0;h<m;h++) 79                     if((st[j]&s[h]) && map[i][h]=='H') break; 80                     else if(st[j]&s[h]) temp++; 81                 if(h<m) continue; 82                 for(h=0;h<k;h++) 83                 { 84                     if(st[h]>=s[m]) break; 85                     if(st[j]&st[h]) continue; 86                     if(i==1) DP[1][j][h]=max(DP[1][j][h],DP[0][h][0]); 87                     else 88                     { 89                         for(i1=0;i1<k;i1++) 90                         { 91                             if(st[i1]>=s[m]) break; 92                             if(!(st[j]&st[i1]) && !(st[h]&st[i1])) DP[i][j][h]=max(DP[i][j][h],DP[i-1][h][i1]); 93                         } 94                     } 95                 DP[i][j][h]+=temp; 96                 ans=max(DP[i][j][h],ans); 97                 } 98             } 99         }100         printf("%d\n",ans);101     }102     return 0;103 }

转载于:https://www.cnblogs.com/183zyz/archive/2011/07/30/2122143.html

pku 1185 炮兵阵地相关推荐

  1. 【状态dp】poj 1185 炮兵阵地(三维dp)

    poj 1185 炮兵阵地 http://poj.org/problem?id=1185 问题描述:给你一个n行m列的P-H矩阵,H表示不能安置炮兵,1可以安置炮兵,要求炮兵攻击管辖内不能在安置其他炮 ...

  2. POJ 1185 炮兵阵地 (状压DP)

    炮兵阵地 Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 14869   Accepted: 5575 Description ...

  3. POJ 1185 炮兵阵地(动态规划+状态压缩)

    炮兵阵地 Description 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平原( ...

  4. POJ 1185 炮兵阵地(状态压缩DP)

    Description 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平原(用&quo ...

  5. POJ 1185 炮兵阵地(状压dp)

    http://poj.org/problem?id=1185 题意: 思路: 每一行最多只有10列,所以可以用二进制来表示每一行的状态. d[i][j][k]表示第i行状态为k时,并且上一行状态为j时 ...

  6. POJ 1185 炮兵阵地 【状压DP】

    <题目链接> 题目大意: 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平 ...

  7. poj -- 1185 炮兵阵地

    题解:二进制压缩,枚举每行存在的状态,判断与前一行的状态的关系,找出最大值 dp[i][j][k] = max(dp[i][j][k] , dp[i-1][k][[l] + p[j]) 表示第i行第j ...

  8. POJ 1185 炮兵阵地 状压dp

    http://poj.org/problem?id=1185 经典题目不必多说,直接贴代码. 1 #include<cstdio> 2 #include<cstring> 3 ...

  9. POJ - 1185 炮兵阵地(状压dp)

    题目链接:点击查看 题目大意:中文题,题意很清晰,不多赘述 题目分析:最基础的状压dp,需要考虑如何转移,因为每一个炸弹所涉及的范围都是上下左右两个格子,我们可以从第一行开始向下转移,这样某一行的状态 ...

最新文章

  1. 100天后 - 100-days-later
  2. 请问大侠maven怎么添加ms的jdbc驱动啊,1.6jdk
  3. 十月 android版本分布,安兔兔发布2018年10月份Android手机性能排行榜
  4. Django项目部署到阿里云服务器上无法发送邮件STMP
  5. Iterator 和 ListIterator 的区别
  6. 一加8渲染图曝光:后置三摄/五种配色可选
  7. docker安装mysql后如何修改默认端口
  8. Windows10 快捷方式失效
  9. mysql 间隙锁_MySQL间隙锁问题
  10. PKI加密体系加密过程及原理
  11. 自定义画圆进度条,带波浪动态效果
  12. 智和信通搭建高可靠、真稳定IT运维平台,助力能源行业高效生产
  13. Android Studio之GsonFormat用法
  14. 解决IE系列浏览器上传页面接收问题
  15. python要学多久才可以,python一般需要学多久
  16. 淘宝要社交:改变买家购买方式 取消商品排名(转载)
  17. 【吾爱破解第一期】破解基础知识之认识壳与程序的特征
  18. PNAS:眼动证据支持行为的“模式完成”理论
  19. 【计算机组成原理】计算机系统概述总结——基本知识要点汇总
  20. 基于扩展卡尔曼滤波的目标跟踪仿真

热门文章

  1. Entity Framework教程
  2. SQLAlchemy_定义(一对一/一对多/多对多)关系
  3. js中json的添加和指定位置的删除
  4. Linux7静默安装Oracle11g教程,亲测实用有效!
  5. javaScript初学者易错点
  6. 《Ext JS权威指南》印出来了,大家很快就能拿到书了
  7. gsea结果分析图怎么看_数据分析怎么做?看这篇就够了!
  8. 苯环的神经网络C6H6
  9. [cpp]c++中的 _t 类的数据类型
  10. 第6章-一阶多智体系统一致性-->6.3 连续时间含时滞多智能体系统一致性