這題我覺得有必要多講講,題目是給了我們三個階段的分數,前四十分還是很好拿的,搜尋加點優化就好了,後面就要用到動態了。
因為他說的事向左或向右殺,所以我可以認為他為了更加優化的答案就盡量的不要繞遠路,就是一路向西殺到底,或者殺到一半在回來殺右邊的。很幸運,我水到了60分,哈哈哈。
講一下正解吧,首先我們要知道,如果你在路上遇到的兵就一定要殺了,所以我們可以設f[i,j],為從i到j殺的人的最大價值,因為他可以在i-j裡面殺乙個,兩個,或者j-i+1個,所以我們迴圈的時候就要確定他到底殺了多少人,用k表示。
前面得出來的,每次都是要殺到一段的底,就可以退出轉移方程
fi[i,j]:=max(fi[i+1,j]+(m-(a[i+1]-a[i])x(k-i+j)),fj[i+1,j]+(m-(a[j]-a[i])x(k-i+j)));
fj的同理得出。
const
maxn=1000;
var fi,fj:array [1..maxn,1..maxn] of longint;
i,j,n,m,k,max,len:longint;
a:array [1..maxn] of longint;
function
cmax
(x,y:longint):longint;
begin
if x>y then
exit(x)
else
exit(y);
end;
begin
assign(input,'kill.in'); reset(input);
assign(output,'kill.out'); rewrite(output);
readln(n,m);
for i:=1
to n do
readln(a[i]);
for i:=1
to n-1
dofor j:=i+1
to n do
if a[i]>a[j] then
begin
a[0]:=a[i];
a[i]:=a[j];
a[j]:=a[0];
end;
for k:=1
to n do
begin
for i:=1
to n do
begin
fi[i,i]:=m-abs(a[i])*k;
fj[i,i]:=fi[i,i];
if fi[i,i]>max then max:=fi[i,i];
end;
for len:=2
to k do
for i:=1
to n-len+1
dobegin
j:=i+len-1;
fi[i,j]:=m+cmax(fi[i+1,j]-(a[i+1]-a[i])*(k-j+i),fj[i+1,j]-(a[j]-a[i])*(k-j+i));
fj[i,j]:=m+cmax(fj[i,j-1]-(a[j]-a[j-1])*(k-j+i),fi[i,j-1]-(a[j]-a[i])*(k-j+i));
end;
for i:=1
to n-k+1
dobegin
if fi[i,i+k-1]>max then max:=fi[i,i+k-1];
if fj[i,i+k-1]>max then max:=fj[i,i+k-1];
end;
end;
writeln(max);
close(input); close(output);
end.
買裝備(特長生準備)
n個物品,物品有物抗和魔抗還有價值,要求物抗和魔抗都到達規定值,然後價值最小。n 21 物抗 21 魔抗 79 價值 800 二維費用揹包,書上的例題 搜尋,對乙個物品只有選和不選兩種狀態,時間就是o 2 21 var i,j,n,m,x,y,k,min longint a,b,w array 1....
偵察兵(特長生準備)
給你乙個n n的矩陣,求 x,y 左上角和右下角的值得和。n 1000 有t個 x,y t 1000 不可以直接暴力,因為要列舉三個變數,就是n 3,一定會超時,然後就想到二維的字首和,在搞個字尾和。去乙個點相加就好了,時間o n 2 n const maxn 1000 var a,f,f1 arr...
特長生模擬 採藥
題目大意 凡凡要去採藥,他採的藥不僅要求揹包的總空間v能放得下所採的藥,還要求藥草的總質量不能超過凡凡所能承受的範圍m。現在給出n種珍惜的藥材,對於每個藥材凡凡都會精準地目測出其質量a i 體積b i 和價值c i 求凡凡所能採到的藥材的最大價值。注意 每種藥材只有乙個。30 資料,所有藥草質量a ...