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. [朴智妍][Lullaby]

    歌词来源:http://music.163.com/#/song?id=484056971 作曲 : Bum/Sophiya/김용신 [作曲 : Bum/Sophiya/k/gi-myong-xin] ...

  2. Elasticsearch学习总结 (Centos7下Elasticsearch集群部署记录)

    一.  ElasticSearch简单介绍 ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口.Elasticse ...

  3. php的垃圾回收机制

    转载请附上本文地址:http://blog.csdn.net/u011957758/article/details/76864400 前言 是的,平时经常听到大牛说到的gc,就是垃圾回收器,全称Gar ...

  4. 个人阅读作业2:结合《No Silver Bullet》谈谈我在软件开发过程的遇到的困难与体会

    英文捉急,只能挑一段看得比较懂的,而且正好和我们现在编程任务联系比较紧密的内容来谈一谈体会. 在<No Silver Bullet>中,作者描述了造成软件本质性困难(essence)的四个 ...

  5. Scrum Meeting 7

                第七次会议 No_00:工作情况 No_01:任务说明 待完成 已完成 No_10:燃尽图 No_11:照片记录 待更新 No_100:代码/文档签入记录 No_101:出席表 ...

  6. bate版说明书

    本游戏是一款手机游戏,学生可以在无聊时打发时间,放松心情.现在只有十关,游戏运行还算可以. 特点: 对alpha版进行了修改,可以进行暂停,重开,返回目录. 画面也进行了优化,不象之前的那么粗超. 游 ...

  7. [BUAA_SE_2017]个人项目-Sudoku

    个人项目作业-数独 Github项目地址 时间预估 PSP2.1 Personal Software Process Stages 预估时间(分钟) 实际耗时(分钟) Planning 计划 60 · ...

  8. scope 前缀开头的方法

    https://learnku.com/docs/laravel/5.6/eloquent/1403 本地范围 本地范围允许定义通用的约束集合以便在应用中复用. 例如, 你可能经常需要获取「受欢迎的」 ...

  9. pandas取值

    #!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2018/5/24 15:03 # @Author : zhang chao # @Fi ...

  10. ES next & Async Await

    ES next & Async Await https://jestjs.io/docs/en/asynchronous#async-await ES7 new async () => ...