POJ1185 炮兵陣地 狀態壓縮DP

2021-09-01 04:46:16 字數 2024 閱讀 4579

1. 為何狀態壓縮:

棋盤規模為n*m,且m≤10,如果用乙個int表示一行上棋子的狀態,足以表示m≤10所要求的範圍。故想到用int s[num]。至於開多大的陣列,可以自己用dfs搜尋試試看;也可以遍歷0~2^m-1,對每個數值的二進位制表示進行檢查;也可以用數學方法(?)

2. 如何構造狀態:

當然,在此之前首先要想到用dp(?)。之後,才考慮去構造狀態函式f(...)。

這裡有乙個鏈式的限制 :某行上的某個棋子的攻擊範圍是2。即,第r行的狀態s[i],決定第r-1行只能取部分狀態s[p];同時,第r行的狀態s[i],第r-1行狀態s[p],共同決定第r-2行只能取更少的狀態s[q]。當然,最後對上面得到的候選s[i], s[p], s[q],還要用地形的限制去篩選一下即可。

簡言之,第r行的威震第r-2行,因此在遞推公式(左邊=右邊)中,必然同時出現r,和r-2兩個行標;由於遞推公式中行標是連續出現的,故在遞推公式中必然同時出現r, r-1和r-2三個行標。由於在遞推公式中左邊包含乙個f(...),右邊包含另乙個f(...),根據抽屜原理,r, r-1, r-2中至少有兩個在同乙個f(...)中,因此狀態函式中必然至少包括相鄰兩行的行號作為兩個維度。這就是為什麼狀態函式要涉及到兩(相鄰的)行,而不是一行。能想到的最簡單形式如下:

dp[r][i][p]:第r行狀態為s[i],第r-1行狀態為s[p],此時從第0行~第r行棋子的最大數目為dp[r][i][p]

遞推公式:

s[p]影響到s[q]的選取

dp[r][i][p]=max+sum[j], 其中sum[j]是狀態s[j]中1的個數

s[i]影響到s[p]的選取                 |

**:

#include #include #include #define max(a,b) (a)>(b)?(a):(b) 

using namespace std;

int dp[105][65][65]; //d[i][j][k]: 「第i行狀態是s[j],第i-1行狀態是s[k]」的

int s[105]; //一行的狀態選擇s[0], s[1], ... , s[k-1]

int n,m; //n行×m列

int k; //一行的所有狀態數

int map[105]; //'h''p'地圖map[0]~map[n-1],地圖每一行map[line]: 1001 表示hpph

int sum[105];

/* 很久就看推薦題目有這個了,一直沒做,因為看了好幾次沒看懂,都說dp,這幾天看了狀態壓縮後明白了,其實就是用

二進位制來表示各個位置的狀態然後進行列舉,把狀態放進陣列裡就行,在這裡用dp[i][j][k]表示第i行,當前j狀態,

i-1行是k狀態時候的最大炮數 dp[i][j][k]=max(dp[i][j][k],dp[i-1][k][p]+sum[j])

caution:

1. 所有下標均從0開始

2. m<=10保證了可以用乙個int儲存一行的狀態

*///狀態s[x]是否造成行衝突

bool ok(int x)

//狀態s[x]下有多少個1

int getsum(int x)

return num;

} void find()

} k=0;

find();

//1. 初始化第0行狀態(只考慮有效狀態,無效狀態為-1)

for(i=0;i

if(!(s[i]&map[0])) //s[i]為1的位如果對應平原(0),則&運算後為0

dp[0][i][0]=sum[i];

//2. 計算第1~n-1行狀態(碰到無效狀態,continue)

for(int r=1;r

} }

}int ans=0;

for(i=0;i

for(int j=0;j

ans=max(ans,dp[n-1][i][j]);

printf("%d\n",ans);

} system("pause");

return 0;

}

poj1185 炮兵陣地(狀態壓縮)

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

poj 1185炮兵陣地(狀態壓縮)

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

POJ1185 炮兵陣地 狀態壓縮DP

感覺和3254很像,不過這次的間隔變成兩格,當前行的狀態與上兩行的狀態有關。狀態轉移方程 dp k q i max dp k q i dp q j i num k num k 表示狀態k的炮兵數量 dp k q i 表示當前第i行為狀態k上一行的狀態為q的炮兵數量總數。炮兵陣地 time limit...