炮兵陣地
time limit:1000ms memory limit:65536k
total submit:30 accepted:14
description
司令部的將軍們打算在n*m的網格地圖上部署他們的炮兵部隊。乙個n*m的地圖由n行m列組成,地圖的每一格可能是山地(用「h」 表示),也可能是平原(用「p」表示),如下圖。在每一格平原地形上最多可以布置一支炮兵部隊(山地上不能夠部署炮兵部隊);一支炮兵部隊在地圖上的攻擊範圍如圖中黑色區域所示:
如果在地圖中的灰色所標識的平原上部署一支炮兵部隊,則圖中的黑色的網格表示它能夠攻擊到的區域:沿橫向左右各兩格,沿縱向上下各兩格。圖上其它白色網格均攻擊不到。從圖上可見炮兵的攻擊範圍不受地形的影響。
現在,將軍們規劃如何部署炮兵部隊,在防止誤傷的前提下(保證任何兩支炮兵部隊之間不能互相攻擊,即任何一支炮兵部隊都不在其他支炮兵部隊的攻擊範圍內),在整個地圖區域內最多能夠擺放多少我軍的炮兵部隊。
input
第一行包含兩個由空格分割開的正整數,分別表示n和m;
接下來的n行,每一行含有連續的m個字元(『p』或者『h』),中間沒有空格。按順序表示地圖中每一行的資料。n≤100;m≤10。
output
僅在第一行包含乙個整數k,表示最多能擺放的炮兵部隊的數量。
sample input
5 4sample outputphpp
pphh
pppp
phpp
phhp
6題目大意:
給出乙個n*m的圖,圖上有一些點可以放棋子,有一些不能。每個棋子的上下左右相鄰2個格仔內不能放置其他棋子,問最多能放幾個棋子。
題解:狀態壓縮dp
每一行棋子放置的狀態我們可以用乙個二進位制數表示,那麼每一行能放置的所有狀態可以預處理得出的。設s[i]為一行中可放置的第i種狀態(用dfs求出)
設f[i,j,k]為第i行的狀態為第j個狀態,i-1行為第k個狀態時能放置的最大數量,易得出f[i,j,k]=max(f[i-1,k,l])+c[j] |s[j] s[k] s[l] 不衝突|
c[i]表示第i種狀態中1的個數(即放置炮兵的個數)
在dp過程中要判斷兩個狀態不衝突,實際上就是s[i] and s[j]=0,要注意的是圖中有一些點不能放炮兵,在讀入時要處理出每一行不能放的狀態,在判斷時使其不與當前行狀態衝突。
const
maxn=100;
maxm=100;
var f:array[0..maxn,0..maxm,0..maxm]of longint;
a:array[-2..maxn]of longint;
s,c:array[0..maxm]of longint;
b:array[0..10]of longint;
n,m,sum,ans,p:longint;
i,j,k,l:longint;
procedure init;
var i,j:longint;
ch:char;
begin
readln(n,m);
for i:=1 to n do
begin
for j:=1 to m do
begin
read(ch);
if ch='p' then a[i]:=a[i]*2 else if ch='h' then a[i]:=a[i]*2+1;
end;
readln;
end;
sum:=0;
end;
function max(a,b:longint):longint;
begin
if a>b then exit(a) else exit(b);
end;
procedure dfs(dep:longint);
var i:longint;
begin
if dep>m then
begin
inc(sum);s[sum]:=0;
for i:=1 to m do
begin
s[sum]:=s[sum]*2+b[i];
inc(c[sum],b[i]);
end;
exit;
end;
dfs(dep+1);
b[dep]:=1;
dfs(dep+3);
b[dep]:=0;
end;
begin
init;
dfs(1);
for i:=1 to n do
for j:=1 to sum do
for k:=1 to sum do
begin
for l:=1 to sum do
if (s[j] and s[k])+(s[j] and s[l])+(s[k] and s[l])+(s[j] and a[i])+(s[k] and a[i-1])+(s[l] and a[i-2])=0 then
f[i,j,k]:=max(f[i,j,k],f[i-1,k,l]);
f[i,j,k]:=f[i,j,k]+c[j];
end;
for i:=1 to sum do
for j:=1 to sum do
if f[n,i,j]>ans then ans:=f[n,i,j];
writeln(ans);
end.
NOI 2001 炮兵陣地
分析 本來想的和周偉nei胖子差不多 但是感覺時間會炸,於是又苟且看了講解 發現胖子果然用會炸的方法 但是畢竟十幾年前的題了 資料略弱 dp i j k 表示前i行中,第i行狀態為j,第i 1行狀態為k時炮兵的最多數量 狀態均為01的二進位制串 方程很好寫 dp i j k max dp i j k...
NOI2001 炮兵陣地
司令部的將軍們打算在n m的網格地圖上部署他們的炮兵部隊。乙個n m的地圖由n行m列組成,地圖的每一格可能是山地 用 h 表示 也可能是平原 用 p 表示 如下圖。在每一格平原地形上最多可以布置一支炮兵部隊 山地上不能夠部署炮兵部隊 一支炮兵部隊在地圖上的攻擊範圍如圖中黑色區域所示 如果在地圖中的括...
NOI2001 炮兵陣地
司令部的將軍們打算在n m的網格地圖上部署他們的炮兵部隊。乙個n m的地圖由n行m列組成,地圖的每一格可能是山地 用 h 表示 也可能是平原 用 p 表示 如下圖。在每一格平原地形上最多可以布置一支炮兵部隊 山地上不能夠部署炮兵部隊 如果在地圖中的括號所標識的平原上部署一支炮兵部隊,則圖中的黑色的網...