題目描述就不贅述了。
解題思路:
這道題的判斷合法的方式比較常見,簡單位運算即可,關鍵是空間和狀態轉移方程。
預處理:可以證明有效的方案數不會超過200,這個數字只是我估算的上界,不嚴格,預處理出每一行的方案即可。
狀態轉移方程:每一行由上一行遞推得到,f[i][j][k]表示前i行,第i行狀態為j,第i-1行狀態為k的方案數。
第一行和第二行預處理一下,
第三行之後就轉移吧.
f[i][j][k]=max(f[i][j][k],f[i-1][k][t]+cnt[i][j]);
這樣第i行狀態可以由第i-1行和第i-2行得到。
時間複雜度:o(100*200*200*200)
空間複雜度:o(100*200*200)
**:
#include#define ll long long#define r register
using
namespace
std;
int n,m,a[130],ans,w[130][230],num[230],f[105][230][230],cnt[130][230
];inline
int count(r int
x) inline
int check(r int x,r inty)
intmain()
for(r int i=1;i<=n;i++)
for(r int j=0;j<=(1
<1;j++)
//在a[i]中 1 為山地
for(r int i=1;i<=num[1];i++)
ans=max(ans,cnt[1
][i]);
for(r int i=1;i<=num[2];i++)//
第二行狀態
}for(r int i=3;i<=n;i++)//
枚舉行 ans=max(ans,f[i][j][k]); }}
}printf("%d
",ans);
return0;
}//dp陣列 和 方程
//狀態轉移
這道題最主要的就是時間空間的分析和狀態轉移方程了。
P2704 NOI2001 炮兵陣地
炮兵陣地 這道題之前已經討論過二進位制狀壓的方法了,通過 滾動陣列 預處理 的方法可以達到極高效率。但是這裡給出一種更具有普適性的方法。對於和之前多個階段有關聯的 dp,我們可以使用多進製狀壓來處理。具體方法 假設進行 k 進製狀壓,將每一位的狀態表示為 0 k 1 中的某個數,規定狀態之間的轉移方...
P2704 NOI2001 炮兵陣地
題目鏈結 狀壓dp。這個炮可以打到上面兩行,這個點卡了我很久,我一開始就壓一行的狀態,發現會無線套娃 當前行可能會打到上兩行,你還不能只判斷當前行與上一行是否匹配,還得判斷上兩行 判了上一行還要判斷上一行的上兩行。為了解決這個問題,我們可以直接把兩行的狀態放到乙個陣列裡,這樣問題就解決了。轉移方程 ...
洛谷 P2704 NOI2001 炮兵陣地
給出n m的地圖,有很多空地p跟山地h,炮台可以攻擊周邊 求最多能放多少個炮台並且他們互不攻擊。n 100 m 10 這題是狀壓dp的一道經典題目,對於每行10個東東可以放就是2 10種可能,這樣轉移就會tle 所以我們發現因為任意2個炮之間距離至少為2,所以我們每行存在的可行狀態至多不超過2 5 ...