POJ 1185 炮兵陣地 動態規劃 狀態壓縮

2021-09-06 07:49:26 字數 1642 閱讀 7459

由於遞推的時候依賴於三個連續層的關係.一開始想著直接三重for迴圈,但是這裡有個問題就是上一層的0位置上包括著上上層是0和1兩種可能,而後者又對當前行有約束,因此該方法不行.當然有乙個辦法就是增加狀態數,讓狀態能夠表示是從1還是從0轉移過來的.(這題有個解法是採用多進製的狀態壓縮). 網上瞄了別人的一眼解題報告. 瞬間頓悟,竟然三層之間發生關係,那麼就直接把連續的兩層記錄起來,雖然說空間上不及多進製優美. 但是卻能夠去描述這些個問題.

**如下:

#include #include 

#include

#include

using

namespace

std;

/*題意:給定乙個矩陣,有點點能夠放置部隊,有的不行,部隊能夠進攻上下左右各2個格仔,現在

問要求所有部隊火力不能夠覆蓋友方部隊,問最多能夠擺放多少部隊.

解法:其實這題單單就一行的狀態來說,狀態的約束條件更強,可以預見其合法狀態也很少,何

況給定列本身就不超過10, 因此一行中的合法狀態一定很少. 該題難點在於如何將上下

火力不覆蓋友方部隊很好的表示出來.乙個可行的做法是對設定狀態是dp[k][i][j]表示

第k層的狀態為i,第i-1層狀態為j時最多放置多少部隊. 所以又動態方程:

dp[k][i][j] = sum(dp[k-1][j][k]) 其中k滿足不和i發生衝突

*/int n, m, sta[65], idx; //

當m=10的時候,合法的狀態不超過65個

int g[105], dp[105][65][65]; //

該dp的第一維真正意義上表示乙個狀態,而不是狀態的下表

void display(int

x)

else printf("0 "

); }

puts(

"");

getchar();

}void dfs(int pos, int statu, int

dist)

dfs(pos+1, statu<<1, dist+1

);

if (dist >= 2) }

bool legal(int x, int

y) bool judge(int x, int

y) int

get(int

x) }

return

ret;

}int

dp()

}

return

ret;

}//初始化第一,二層的狀態

for (int i = 1; i <= idx; ++i) }}

for (int k = 3; k <= n; ++k)

for (int m = 1; m <= idx; ++m)

}dp[k][i][j] += get

(sta[i]);}}

}for (int i = 1; i <= idx; ++i)

}return

ret;

}int

main()

}printf(

"%d\n

", dp());

}return

0;

}

POJ 1185 炮兵陣地(動態規劃 狀態壓縮)

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

poj 1185 炮兵陣地

題目鏈結 題意 在n m的網格地圖上部署炮兵部隊。地圖的每一格可能是山地 用 h 表示 也可能是平原 用 p 表示 如下圖。在每一格平原地形上最多可以布置一支炮兵部隊 山地上不能夠部署炮兵部隊 一支炮兵部隊在地圖上的攻擊範圍如圖中黑色區域所示 如果在地圖中的灰色所標識的平原上部署一支炮兵部隊,則圖中...

POJ 1185 炮兵陣地

include include include include include include include include include include include include include include define sz v int v size define rep i,n ...