Solution:状态压缩

因为设置炮兵的局限性(同行两炮兵相差要大于2),一行10个数最多有60种可能性(程序计算)

  其中判断可能性的好方法是:

if ((i & (i << 1))==0 && (i & (i << 2))==0
             && (i & (i >> 1))==0 && (i & (i >> 2))==0)

      代表不能有左1,左2,右1,右2相邻的1

行数相差2以上,两行互相之间没有影响

  

  if j,k,l不冲突

f[i][j][k]=max(f[i][j][k],f[i-1][k][l]+v[j])

其中i为第i行,j为第i行的状态,k为第(i-1)行的状态,l为第(i-2)行的状态,v为在第i行的状态j可以设置的炮兵数

f[i][j][k]为前i行,以j,k状态下设置的最多的炮兵数,而第i行设置炮兵只与i-1,i-2行有关(前i行中)

时间复杂度:n*f(t)*f(t)*f(t)

f(t)为一行t个数,设置炮兵的可能性

n<=100,m<=10 即 100*60*60*60=21600000

事实上,由于地形的限制(山地不能建炮兵)和行与行之间的限制(同列两炮兵相差要大于2),时间复杂度小于此

 #include <stdio.h>
#include <stdlib.h> int max(int a,int b)
{
if (a>b)
return a;
else
return b;
} int main()
{
//100*1024*1024
int i,j,k,l,m,n,f[][][],use[][],map[]={},s[],v[]={},ans=,g=;
int er[]={,,,,,,,,,,};
char c;
scanf("%d%d",&m,&n);
scanf("%c",&c);
for (i=;i<m;i++)
{
for (j=n-;j>=;j--)
{
scanf("%c",&c);
if (c=='H')
map[i]+=er[j];
}
scanf("%c",&c);
}
/*
for (i=0;i<m;i++)
printf("%d\n",map[i]);
printf("\n");
*/
for (i=;i<er[n];i++)
if ((i & (i << ))== && (i & (i << ))==
&& (i & (i >> ))== && (i & (i >> ))==)
{
ans++;
s[ans]=i;
j=i;
while (j)
{
j&=(j-);
v[ans]++;
}
}
/*
printf("ans=%d\n",ans);
for (i=0;i<er[n];i++)
printf("%d %d个 ",s[i],v[i]);
*/
//init
for (i=;i<m;i++)
use[i][]=;
for (i=;i<m;i++)
for (j=;j<=ans;j++)
for (k=;k<=ans;k++)
f[i][j][k]=;
//row
for (i=;i<m;i++)
//each row , posibility
for (j=;j<=ans;j++)
if ((map[i] & s[j])==)
{
use[i][]++;
use[i][use[i][]]=j; //编号 cur + bcur + bpre
if (i>=)
{
for (k=;k<=use[i-][];k++)
if ((s[j] & s[use[i-][k]])==)
for (l=;l<=use[i-][];l++)
if ((s[j] & s[use[i-][l]])==
&& (s[use[i-][k]] & s[use[i-][l]])==)
f[i][j][use[i-][k]]=max(f[i][j][use[i-][k]],f[i-][use[i-][k]][use[i-][l]]+v[j]);
}
else if (i==)
{
for (k=;k<=use[i-][];k++)
if ((s[j] & s[use[i-][k]])==)
f[i][j][use[i-][k]]=max(f[i][j][use[i-][k]],f[i-][use[i-][k]][]+v[j]);
}
else
f[i][j][]=v[j]; }
if (m!=)
{
for (k=;k<=use[m-][];k++)
for (l=;l<=use[m-][];l++)
if ((s[use[m-][k]] & s[use[m-][l]])==)
g=max(g,f[m-][use[m-][k]][use[m-][l]]);
}
else
{
for (k=;k<=use[m-][];k++)
g=max(g,f[m-][use[m-][k]][]);
}
printf("%d\n",g);
/*
for (i=0;i<m;i++)
{
for (j=1;j<=ans;j++)
for (k=1;k<=ans;k++)
//printf("f[%d][%d][%d]=%d\n",i,j,k,f[i][j][k]);
printf("%d ",f[i][j][k]);
printf("\n\n");
}
for (k=1;k<=use[m-1][0];k++)
for (l=1;l<=use[m-2][0];l++)
printf("%d %d %d\n",s[use[m-1][k]],s[use[m-2][l]],f[m-1][use[m-1][k]][use[m-2][l]]);
*/
return ;
}

错误代码:

  if j,k,l不冲突

  f[i][j]=max(f[i][j],f[i-2][l]+v[k]+v[j]);

其中i为第i行,j为第i行的状态,k为第(i-1)行的状态,l为第(i-2)行的状态,v为在第i行的状态j可以设置的炮兵数

f[i][j]为前i行,以j状态下设置的最多的炮兵数

  但是l,k可能会发生冲突,在f[i-2][l]下,第(i-1)行不能用k状态

第三行,在第1,4个建炮兵情况下,

8 4

HPPH

PPPP-----是以右上方的P为基础,与第三行发生冲突

HPPH

PHHP

PHHP

HPPH

PPPP

HPPH

 #include <stdio.h>
#include <stdlib.h> int max(int a,int b)
{
if (a>b)
return a;
else
return b;
} int main()
{
int i,j,k,l,m,n,f[][],use[][],map[]={},s[],v[]={},ans=,g=;
int er[]={,,,,,,,,,,};
char c;
scanf("%d%d",&m,&n);
scanf("%c",&c);
for (i=;i<m;i++)
{
for (j=n-;j>=;j--)
{
scanf("%c",&c);
if (c=='H')
map[i]+=er[j];
}
scanf("%c",&c);
}
/*
for (i=0;i<m;i++)
printf("%d\n",map[i]);
printf("\n");
*/
for (i=;i<er[n];i++)
if ((i & (i << ))== && (i & (i << ))==
&& (i & (i >> ))== && (i & (i >> ))==)
{
ans++;
s[ans]=i;
j=i;
while (j)
{
j&=(j-);
v[i]++;
}
}
/*
printf("ans=%d\n",ans);
for (i=0;i<er[n];i++)
printf("%d ",v[i]);
*/
for (i=;i<m;i++)
use[i][]=;
for (i=;i<m;i++)
for (j=;j<er[i];j++)
f[i][j]=;
//row
for (i=;i<m;i++)
{
//each row , posibility
for (j=;j<=ans;j++)
if ((map[i] & s[j])==)
{
use[i][]++;
use[i][use[i][]]=s[j];
if (i>=)
{
for (k=;k<=use[i-][];k++)
if ((s[j] & use[i-][k])==)
for (l=;l<=use[i-][];l++)
if ((s[j] & use[i-][l])==
&& (use[i-][k] & use[i-][l])==)
f[i][s[j]]=max(f[i][s[j]],f[i-][use[i-][l]]+v[use[i-][k]]+v[s[j]]);
}
else if (i==)
{
for (k=;k<=use[i-][];k++)
if ((s[j] & use[i-][k])==)
f[i][s[j]]=max(f[i][s[j]],f[i-][use[i-][k]]+v[s[j]]);
}
else
f[i][s[j]]=v[s[j]];
}
}
for (i=;i<=use[m-][];i++)
g=max(g,f[m-][use[m-][i]]);
printf("%d\n",g);
/*
for (i=0;i<m;i++)
{
for (j=0;j<er[n];j++)
printf("%d ",f[i][j]);
printf("\n");
}
*/
return ;
}

poj1185炮兵阵地 正确代码及错误代码分析的更多相关文章

  1. [poj1185]炮兵阵地_状压dp

    炮兵阵地 poj-1185 题目大意:给出n列m行,在其中添加炮兵,问最多能加的炮兵数. 注释:n<=100,m<=10.然后只能在平原的地方建立炮兵. 想法:第2到状压dp,++.这题显 ...

  2. POJ1185 炮兵阵地 —— 状压DP

    题目链接:http://poj.org/problem?id=1185 炮兵阵地 Time Limit: 2000MS   Memory Limit: 65536K Total Submissions ...

  3. POJ1185 炮兵阵地 和 POJ2411 Mondriaan's Dream

    炮兵阵地 Language:Default 炮兵阵地 Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 34008 Accepted ...

  4. POJ1185炮兵阵地【动态规划】

    炮兵阵地 Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 26892   Accepted: 10396 Descriptio ...

  5. poj1185 炮兵阵地【状压DP】

    炮兵阵地 Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 32802   Accepted: 12650 Descriptio ...

  6. POJ1185 炮兵阵地 状态压缩

    因为不知道不同的博客怎么转,就把别人的复制过来了,这个题解写的非常好,原地址为: http://hi.baidu.com/wangxustf/item/9138f80ce2292b8903ce1bc7 ...

  7. POJ1185炮兵阵地(状态压缩DP)

    POJ飞翔.数据弱 ZQOJ飞翔 数据强 Description 司令部的将军们打算在N×M的网格地图上部署他们的炮兵部队.一个N×M的地图由N行M列组成,地图的每一格可能是山地(用"H&q ...

  8. POJ1185 - 炮兵阵地(状态压缩DP)

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

  9. poj1185炮兵阵地

    #include <iostream> #include <cstdio> #include <cmath> #include <algorithm> ...

随机推荐

  1. PLSQL使用技巧 如何设置默认显示My Objects、记住密码等

    https://www.cnblogs.com/yilinzi/p/7144852.html PL/SQL Developer实现双击table查询 https://blog.csdn.net/zhy ...

  2. 领跑衫获奖感言 & 课程总结

    很荣幸在最后一次课获得了黄色领跑衫.在此,我要感谢教师杨贵福,感谢<构建之法>的作者邹欣老师和出版人周筠老师,感谢“耐撕”团队的队员们. 作为旁听生,最后一堂课,有些不舍.不多说,先上图, ...

  3. 北航学堂Android客户端Beta阶段测试报告

    我们已经知道的bug如下: 1.在没有网络的情况下,我们的程序会直接崩溃,没有弹出提醒网络异常的错误,这是个比较严重的bug,我们在6号7号 考试结束之后会进行修改: 有待进行的优化: 1.UI界面的 ...

  4. 《Linux及安全》课程实践二

    编译生成新内核 一.实践原理 Linux模块是一些可以作为独立程序来编译的函数和数据类型的集合.之所以提供模块机制,是因为Linux本身是一个单内核.单内核由于所有内容都集成在一起,效率很高,但可扩展 ...

  5. 最新广商小助手 项目进展 OpenGL ES 3D在我项目中引用 代码太多只好选重要部分出来

    package com.example.home; import java.io.IOException; import java.io.InputStream; import javax.micro ...

  6. 在centos7虚拟机上挂载镜像,并设置yum源(包括遇到的问题)

    挂载镜像方法很简单: mkdir /etc/a mount /dev/cdrom /etc/a 查看挂载情况  : df -h 修改yum源文件 : 先把 CentOS-Base.repo 文件名改一 ...

  7. suqid透明正向代理

    如果想实现透明正向代理,则必需将用户的网关IP指向 Squid 服务器,而此后便无需再修改浏览器选项 在命令行 <菜单+R> 中使用 ping  命令: ping  www.baidu.c ...

  8. Wshshell 脚本简单学习

    WshShell 的简单语法 学习 同事给了一个脚本自动执行  部署命令 感觉挺好的 , 年前一直说要学习一下 但是一直没有学习(自己太懒了) 这次简单总结一下. 创建对象: Set WshShell ...

  9. Oracle 数据库 Only 导出空表的方法

    1. 之前因为oracle11.2.0.1 的bug(deferred_segment_creation) 引起无法将空表导出. 有时给同事解释上半个小时他们也不知道 如何处理 或者是 他们不会用ex ...

  10. React componentWillUpdate

    <!DOCTYPE html><html><head lang="en"> <meta charset="UTF-8" ...