Luogu P2704 NOI2001 炮兵陣地

2021-10-12 07:04:14 字數 1342 閱讀 8028

司令部的將軍們打算在n*m的網格地圖上部署他們的炮兵部隊。乙個n*m的地圖由n行m列組成,地圖的每一格可能是山地(用」h」 表示),也可能是平原(用」p」表示),如下圖。

在每一格平原地形上最多可以布置一支炮兵部隊(山地上不能夠部署炮兵部隊);一支炮兵部隊在地圖上的攻擊範圍如圖中黑色區域所示:

如果在地圖中的灰色所標識的平原上部署一支炮兵部隊,則圖中的黑色的網格表示它能夠攻擊到的區域:沿橫向左右各兩格,沿縱向上下各兩格。

圖上其它白色網格均攻擊不到。

從圖上可見炮兵的攻擊範圍不受地形的影響。

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

由於每一行所擺的炮兵只有前兩行有關,所以可以用狀壓dp, 如果暴力儲存1024個狀態的話會mle,但不難發現其中有用的就只有最多60個狀態,所以可以減少很多空間,而當前層數只和前兩層有關,所以可以考慮g[i][j][k]表示第i層狀態為j,i-1層狀態為k的最大值。

#include #include #include using namespace std;

const int n = 105, m = 1 << 11;

vectorv[n];

int f[61][61][61],n,m;

int g[n][61][61];

bool st[n][20];

int id[m],cnt[m], idx;

int count(int x)

return res;

}bool check(int x)

return true;

}int main()

memset(cnt,-1,sizeof cnt);

memset(id,-1,sizeof id);

for(int i = 0; i < 1 << m; i ++)

if(check(i))

if(flag)v[j].push_back(i);}}

int ans = 0;

for(int i = 1; i <= n; i ++)

else

for(int t = 0; t < v[i-2].size(); t ++)

g[i][j][k] = maxv;

ans = max(ans,maxv);}}

cout << ans << endl;

return 0;

}

Luogu P2704 NOI2001 炮兵陣地

gate 還是狀壓dp.因為int開成bool了de了好久,最後還是wjh幫忙看出來的qaq f i k j 代表第i行,狀態為j,上一行狀態為k,上上行的狀態為kk 四重迴圈,保證j,k j,kk k,kk不衝突的前提下,有 f i k j max f i kk k sum j 因為狀態太多了存不...

luogu2704 NOI2001 炮兵陣地

題目鏈結 因為m 10,考慮狀壓dp 先dfs搜出所有可能狀態 f i j k 表示上上行是 i,上行是 j,第 k 行取得的最大值 但如果直接開滿陣列,mle 考慮滾動陣列 此題只需保留2個狀態,上上行,上行 所以用四層迴圈列舉 超時 考慮剪枝 放進上上行時先與題述條件對比 放入上行是與上上行和題...

NOI 2704 尋找平面上的極大點

題意 根據提示,只有位於單獨顏色上的點或者說只有右上角的點才是極大點,所以我對每乙個點與x和y軸組成的矩形進行標記,將其中每個點的標記值 最後只有標記值為1的點,才是我們要找的點 include include include include include include using namesp...