P2704 NOI2001 炮兵陣地

2022-05-07 17:42:11 字數 956 閱讀 4939

題目鏈結

​ 狀壓dp。

​ 這個炮可以打到上面兩行,這個點卡了我很久,我一開始就壓一行的狀態,發現會無線套娃:當前行可能會打到上兩行,你還不能只判斷當前行與上一行是否匹配,還得判斷上兩行;判了上一行還要判斷上一行的上兩行。。。。

​ 為了解決這個問題,我們可以直接把兩行的狀態放到乙個陣列裡,這樣問題就解決了。

​ 轉移方程:\(dp[i][f][g] = max(calc(f) + dp[i - 1][g][lg])\)。\(f\)為當前行的狀態,\(g\)為上一行的狀態,\(lg\)為上兩行的狀態, \(calc(f)\)是計算當前行的炮兵數。

#include using namespace std;

inline long long read()

const int n = 105, m = 2000;

int n, m, ans;

int num[n], c[n][m], s[n][m], mat[n][n], dp[n][m][m];

int judge(int x, int s)

return 1;

}void make_pre_s()

int calc(int s)

int match(int s1, int s2)

int main()

make_pre_s(); // 預處理出所有合法狀態

num[0] = 1;

for(int i = 1;i <= num[1]; i++)

dp[1][s[1][i]][0] = calc(s[1][i]);

for(int i = 2;i <= n; i++) }}

}}

for(int s1 = 1;s1 <= num[n]; s1++)

}printf("%d", ans);

return 0;

}

P2704 NOI2001 炮兵陣地

炮兵陣地 這道題之前已經討論過二進位制狀壓的方法了,通過 滾動陣列 預處理 的方法可以達到極高效率。但是這裡給出一種更具有普適性的方法。對於和之前多個階段有關聯的 dp,我們可以使用多進製狀壓來處理。具體方法 假設進行 k 進製狀壓,將每一位的狀態表示為 0 k 1 中的某個數,規定狀態之間的轉移方...

P2704 NOI2001 炮兵陣地 題解

題目描述就不贅述了。解題思路 這道題的判斷合法的方式比較常見,簡單位運算即可,關鍵是空間和狀態轉移方程。預處理 可以證明有效的方案數不會超過200,這個數字只是我估算的上界,不嚴格,預處理出每一行的方案即可。狀態轉移方程 每一行由上一行遞推得到,f i j k 表示前i行,第i行狀態為j,第i 1行...

洛谷 P2704 NOI2001 炮兵陣地

給出n m的地圖,有很多空地p跟山地h,炮台可以攻擊周邊 求最多能放多少個炮台並且他們互不攻擊。n 100 m 10 這題是狀壓dp的一道經典題目,對於每行10個東東可以放就是2 10種可能,這樣轉移就會tle 所以我們發現因為任意2個炮之間距離至少為2,所以我們每行存在的可行狀態至多不超過2 5 ...