poj1185 三維狀壓dp

2021-07-16 20:38:54 字數 1815 閱讀 4743

description

司令部的將軍們打算在n*m的網格地圖上部署他們的炮兵部隊。乙個n*m的地圖由n行m列組成,地圖的每一格可能是山地(用"h" 表示),也可能是平原(用"p"表示),如下圖。在每一格平原地形上最多可以布置一支炮兵部隊(山地上不能夠部署炮兵部隊);一支炮兵部隊在地圖上的攻擊範圍如圖中黑色區域所示: 

如果在地圖中的灰色所標識的平原上部署一支炮兵部隊,則圖中的黑色的網格表示它能夠攻擊到的區域:沿橫向左右各兩格,沿縱向上下各兩格。圖上其它白色網格均攻擊不到。從圖上可見炮兵的攻擊範圍不受地形的影響。 

現在,將軍們規劃如何部署炮兵部隊,在防止誤傷的前提下(保證任何兩支炮兵部隊之間不能互相攻擊,即任何一支炮兵部隊都不在其他支炮兵部隊的攻擊範圍內),在整個地圖區域內最多能夠擺放多少我軍的炮兵部隊。 

input

第一行包含兩個由空格分割開的正整數,分別表示n和m; 

接下來的n行,每一行含有連續的m個字元('p'或者'h'),中間沒有空格。按順序表示地圖中每一行的資料。n <= 100;m <= 10。

output

僅一行,包含乙個整數k,表示最多能擺放的炮兵部隊的數量。

sample input

5 4

phpp

pphh

pppp

phpp

phhp

sample output

6
思路:首先把所有合法狀態預處理出來,可知1<<10內最多有60種合法狀態,用d[i][j][k]表示第i行狀態為j,第i-1行狀態為k時的最大值,即遍歷i-2行狀態,找到i,i-1行狀態確定時其最大值,狀態轉移方程為dp[i][j][k]=max(dp[i][j][k],dp[i-1][k][t]+sum[j]),sum[j]為j狀態時1的數量

這個找bug找了一天,才發現預處理第一行時dp[1][i][0]寫為dp[1][0][i]了,以後找不出bug時,可以把所有狀態值都列印出來,不管狀態之間轉移關係,直接手算每個狀態的對應值,看看是否正確。

#include #include #include #include #include #include #include #include #include #include #define ll long long  

#define eps 1e-8

#define maxn 150

#define mod 110119

#define inf 0x3f3f3f3f

#define in freopen("in.txt","r",stdin);

using namespace std;

int n,m;

int map[105];

int cnt=0;

int str[105];

int sum[105];

int dp[105][65][65];

bool ok(int x)

void init()

sum[i]=num;//第i個狀態對應的 1的數量

} }int main(){

// in;

cin>>n>>m;

init();

memset(dp,0,sizeof(dp));

memset(map,0,sizeof(map));

char c;

for(int i=0;i>c;

if(c=='h'){

map[i+1]|=1<

題解 poj1185 狀壓DP

題目鏈結 思路摘抄自大佬部落格 按層數來dp,如果用 dp i j k 來表示在第 i 行,狀態為 j i 1行狀態為 k 時的狀態,那麼有轉移方程 dp i j k max dp i j k dp i 1 k l num i 列舉 i 層數 j 當前層狀態 k 上一層狀態 l 上上層狀態 就可以來...

POJ 1185 經典狀壓dp

做了很久的題 有注釋 include include include include includeusing namespace std int dp 107 107 107 二維記錄上一次 三維記錄此次 dp i k j max dp i k j dp i 1 t k num j t為列舉數且滿...

POJ 1185 經典狀壓dp (模板)

炮兵陣地 time limit 2000ms memory limit 65536k total submissions 26096 accepted 10072 description 司令部的將軍們打算在n m的網格地圖上部署他們的炮兵部隊。乙個n m的地圖由n行m列組成,地圖的每一格可能是山地...