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