炮兵陣地 NOI2001

2021-05-27 13:14:28 字數 2920 閱讀 3432

演算法:位運算+dp+dfs

分析:這是一道非常好的題目,考察的知識非常全面,而且綜合性很強。

首先,根據題意,每個草地只有兩種情況,放與不放,因此在每行最多只有10個位置的情況下列舉每一行的複雜度就是2^10,又因為題目有要求不能相互打到對方,因此在列舉的時候就優化掉了很多選擇。

通過dfs來確定每行選哪些草地放上大炮(話說我就是卡在了這裡,忽略了中間一部分的大炮位置,用的模擬的方法放的大炮- -||)。

最後用乙個簡單的dp方程,即f[i,j,k]=max,表示前i行的狀態是j,前i-1行的狀態是k的最大值可以由前i-1行的狀態是k,i-2的狀態是l再加上第i行是第j種狀態的值轉移而來。

同時要注意本題有點離散化的思想,因為100*600*600會mle,所以用[i,j,k],j即第i行的第j種取法,k即第i-1行的第k種取法。

program p1534;

var n,m:longint;

a:array [0..100,0..10] of char;

tot,sum:array [0..100,0..100] of longint;

f:array [0..100,0..64,0..64] of longint;

procedure init;

var i,j:longint;

ch:char;

begin

readln(n,m);

if (n=1) and (m=1) then

begin

readln(ch);

if ch='h' then writeln(0) else writeln(1);

halt;

end;

for i:=1 to n do

begin

for j:=1 to m do read(a[i,j]);

readln;

end;

end;

procedure dfs(x,start,summ,total:longint);

begin

if start>m then

begin

inc(tot[x,0]);

tot[x,tot[x,0]]:=summ;

sum[x,tot[x,0]]:=total;

exit;

end;

if a[x,start]='p' then

begin

inc(summ,1 shl (start-1));

inc(total);

dfs(x,start+3,summ,total);

dec(summ,1 shl (start-1));

dec(total);

end;

end;

procedure make(x:longint);

begin

tot[x,0]:=1;

tot[x,tot[x,0]]:=0;

sum[x,tot[x,0]]:=0;

dfs(x,1,0,0);

end;

procedure main;

var i:longint;

begin

for i:=1 to n do make(i);

end;

function maxx(x,y:longint):longint;

begin

if x>y then exit(x) else exit(y);

end;

procedure init1;

var i,j:longint;

begin

for i:=1 to tot[2,0] do

begin

for j:=1 to tot[1,0] do

begin

if (tot[1,j] and tot[2,i])=0 then

begin

f[2,i,j]:=maxx(f[2,i,j],sum[1,j]+sum[2,i]);

end;

end;

end;

end;

procedure main1;

var i,j,k,l:longint;

begin

for i:=3 to n do

begin

for j:=1 to tot[i,0] do

begin

for k:=1 to tot[i-1,0] do

begin

for l:=1 to tot[i-2,0] do

begin

if ((tot[i,j] and tot[i-1,k])=0) and ((tot[i,j] and tot[i-2,l])=0) and ((tot[i-1,k] and tot[i-2,l])=0) then

begin

f[i,j,k]:=maxx(f[i,j,k],f[i-1,k,l]+sum[i,j]);

end;

end;

end;

end;

end;

end;

procedure outit;

var i,j,max:longint;

begin

max:=-maxlongint;

for i:=1 to tot[n,0] do

begin

for j:=1 to tot[n-1,0] do

begin

if f[n,i,j]>max then max:=f[n,i,j];

end;

end;

writeln(max);

end;

begin

init;

main;

init1;

main1;

outit;

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 表示 如下圖。在每一格平原地形上最多可以布置一支炮兵部隊 山地上不能夠部署炮兵部隊 如果在地圖中的括號所標識的平原上部署一支炮兵部隊,則圖中的黑色的網...