清兵線(準備特長生)

2021-08-01 06:30:28 字數 1911 閱讀 6667

這題我覺得有必要多講講,題目是給了我們三個階段的分數,前四十分還是很好拿的,搜尋加點優化就好了,後面就要用到動態了。

因為他說的事向左或向右殺,所以我可以認為他為了更加優化的答案就盡量的不要繞遠路,就是一路向西殺到底,或者殺到一半在回來殺右邊的。很幸運,我水到了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 ...