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

2021-09-08 10:31:31 字數 1498 閱讀 7537

司令部的將軍們打算在n*m的網格地圖上部署他們的炮兵部隊,乙個n*m的地圖由n行m列組成,地圖的每一格可能是山地(用"h" 表

示),也可能是平原(用"p"表示)

,例如以下圖。在每一格平原地形上最多可以布置一支炮兵部隊(山地上不可以部署炮兵部隊);一支炮兵部

隊在地圖上的攻擊範圍如圖中黑色區域所看到的:

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

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

#include #include using namespace std;

#define max_size 110

int graph[max_size];

int dp[max_size][max_size][max_size];

// dp[raw][i][j] : 在第 raw 行狀態為 i, 第 raw - 1 行狀態為 j 的情況

int pointer, state_stack[max_size], ones_num[max_size];

// 推斷該狀態左右相鄰兩個單位是否有炮兵衝突

bool isreasonablestate( int state )

// 計算位元位里的 1 的個數

int getonesnum( int state )

return num;

}// 預處理,統計下全部「行」擺放炮兵的合法狀態

void pretreatment( int cols )

}}int main()

}for( int p = 0; p < pointer; ++p )

if( !( state_stack[p] & graph[0] ) )

dp[0][p][0] = ones_num[p];

for( int raw = 1; raw < raws; ++raw )}}

}int ans = 0;

for( int raw_p = 0; raw_p < pointer; ++raw_p )

for( int raw_p_ = 0; raw_p_ < pointer; ++raw_p_ )

ans = max( ans, dp[raws - 1][raw_p][raw_p_] );

cout << ans << endl;

return 0;

}

狀態壓縮DP 炮兵陣地

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

炮兵陣地 狀態壓縮DP

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

狀態壓縮DP 炮兵陣地

這道題真的毒瘤 首先觀察到列的範圍很小,這啟示我們使用狀態壓縮演算法。我們可以預處理出所有橫排不互相攻擊的數字,顯然這些數只有一百來個。用b陣列儲存。我們觀察到一行是否可以防止炮兵和上兩行來決定,我們設f i j k f i j k f i j k 表示第i ii行的狀態為b jb j bj 第i ...