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. Ubuntu apt-get提示被锁住

    执行 apt-get 时提示资源被锁住 E: Could not get lock /var/lib/dpkg/lock - open (11: Resource temporarily unavai ...

  2. mysql操作命令梳理(4)-中文乱码问题

    在平时的mysql运维操作中,经常会碰到插入中文字段后出现乱码的情况,产生中文乱码的原因一般有:1)mysql的编码格式不对,是latin1编码.强烈推荐将mysql下的编码格式都改为utf8,因为它 ...

  3. HDU-6440-费马小定理

    亏我前几天还学数论呢...没有深入研究费马小定理这个东西...做事情一定要静下心来啊... 题目要求满足(m+n)^p=m^p+n^p,要你定义一个封闭的新的加法和乘法运算 我们知道费马小定理中有两种 ...

  4. 个人阅读作业——软件工程M1/M2的总结

    临近学期末,本学期的软件工程课也已经结束了,在此我对软件工程课中,我们团队M1和M2开发阶段中,我做的工作做一个总结 我是DEV,主要工作是等着上级给我分配任务,但是很多时候如果这个活我不干,其他人就 ...

  5. javascript数据类型以及类型间的转化函数

    js 有五种基本数据类型,还有个引用类型 1.undefined 类型,只有一个志undefined 当变量未初始化时都会是这个类型. 2.null 类型,也是只有一个值null,null类型的typ ...

  6. HDOJ2004_成绩转换

    水题:用数组标识各个阶段分数的等级即可. HDOJ2004_成绩转换 #include<stdio.h> #include<stdlib.h> #include<math ...

  7. 递归拼装Tree结构数据

    @Override public List<Map<String, Object>> queryListTree() { List<Map<String,Objec ...

  8. ubuntu在windows下的wubi安装

    转自:http://mp.weixin.qq.com/s?__biz=MjM5NjYxNjU0OQ==&mid=200664819&idx=2&sn=25719890570b1 ...

  9. zabbix 使用问题两个--中文乱码,以及监控ESXi下的虚拟机

    1. 中文乱码 最开始中文显现 长方形不显示文字.解决办法: c:\windows\fonts 下面复制 楷体的字体(字体随意看自己喜欢) 文件名一般为: simkai.ttf 2.将simkai.t ...

  10. 关于linux上文件无法正确显示中文的情况解决

    其实有遇到过多次,而且还有几次是css在预编译的时候,系统编码不对也会报错. 贴一个写的还不错的文章:http://www.360doc.com/content/11/0728/09/7102324_ ...