《洛谷P2704 NOI2001 炮兵陣地》

2022-06-19 19:51:11 字數 1632 閱讀 4213

非常細細細的一題。

首先,這資料量顯然是狀壓。

dp[i][j][k] 表示 到第i行,第i行狀態為j,第i - 1行狀態未k的最大方案數。

我們從上向下考慮的話,每個放置的棋子會被上面兩行棋子的放置狀態所影響。

所以我們每次轉移的時候需要列舉上面的兩行。

這樣的話複雜度就是 n * m * m * m。

這顯然已經超了(但是正解還就是這樣)。

考慮後可以發現,很多狀態都是會衝突被刪掉的,這樣複雜度就少了非常多,所以就夠了。

所以我們可以先預處理出衝突的狀態。

這裡的判斷很巧妙,首先把每一行的原圖轉換成二進位制數,去判斷山地有沒有防炮台。

所以顯然我們去把山地轉成1,然後就可以位運算判斷。

然後對於左右的判斷也可以位運算來加速。

空間不夠必須用滾動陣列。

debug調到裂開。

#includeusing

namespace

std;

typedef

long

long

ll;typedef pair

pii;

const

int n = 5005

;const

int m = 1e5 + 5

;const ll mod = 10007

;#define pi acos(-1)

#define inf 1e9 + 5

#define dbg(ax) cout << "now this num is " << ax << endl;

namespace

fastio

while(c >= '

0' && c <= '9')

return x*f;

}}using

namespace

fastio;

int n,m,a[105

];int dp[3][1

<< 10][1

<< 10],num[1

<< 10

];bool isvis[105][1

<< 10

];int cal(int

state)

intmain()

for(int i = 0;i < (1

<< m);++i) num[i] =cal(i);

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

for(int j = 0;j < (1

<< m);++j)

for(int i = 0;i < (1

<< m);++i)

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

line}}

}int ans = 0

;

for(int i = 0;i < (1

<< m);++i)

for(int j = 0;j < (1

<< m);++j) ans = max(ans,dp[(n - 1) % 3

][i][j]);

printf(

"%d\n

",ans);

system(

"pause");

return0;

}

view code

洛谷 P2704 NOI2001 炮兵陣地

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

洛谷P2704 NOI2001 炮兵陣地

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

洛谷 P2704 NOI2001 炮兵陣地

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