非常細細細的一題。
首先,這資料量顯然是狀壓。
dp[i][j][k] 表示 到第i行,第i行狀態為j,第i - 1行狀態未k的最大方案數。
我們從上向下考慮的話,每個放置的棋子會被上面兩行棋子的放置狀態所影響。
所以我們每次轉移的時候需要列舉上面的兩行。
這樣的話複雜度就是 n * m * m * m。
這顯然已經超了(但是正解還就是這樣)。
考慮後可以發現,很多狀態都是會衝突被刪掉的,這樣複雜度就少了非常多,所以就夠了。
所以我們可以先預處理出衝突的狀態。
這裡的判斷很巧妙,首先把每一行的原圖轉換成二進位制數,去判斷山地有沒有防炮台。
所以顯然我們去把山地轉成1,然後就可以位運算判斷。
然後對於左右的判斷也可以位運算來加速。
空間不夠必須用滾動陣列。
debug調到裂開。
#includeusingview codenamespace
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;
}
洛谷 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 表示 如下圖。在每一格平原地形上最多可以布置一支炮兵部隊 山地上不能夠部署炮兵部隊 一支炮兵部隊在地圖上的攻擊範圍如圖中黑色區域所示 如果在地圖中的灰...