jzoj P1517 揹包問題

2021-08-01 18:25:51 字數 1575 閱讀 7973

題目大意:

從t組物品中選出一些物品,放入揹包中,總空間為v,求裝了物品後,剩餘空間的最小值。

限制條件:從每組物品中挑選物品必須要選取連續的一段。就是說,如果這組物品共有n個: 物品1、物品2、物品3、…、物品n,那麼只能選取物品i、物品i+1、…、物品j,其中1<=i<=j<=n,或者不選。

60%的資料滿足:1 <= ni <= 10

100%的資料滿足:1 <= ni <= 100,1<=v<=5000,1<=t<=10

題解:

可以發現,每組物品,只能選連續的一段且只能選一次,所以我們可以想到dp.

b[i,j]表示第i組物品,是否出現連續一段總體積為j的情況。

f[i,j]表示前t組物品,用了j體積裝物品,能裝載的物品的最大值。

然後怎麼去做b[i,j]?

用乙個字首和去統計,然後暴力去列舉判斷就好了。

然後狀態轉移方程:

f[i,j]:=max(f[i,j-1],max(f[i-1,j-k]+k));

1<=i<=n 0<=j<=m 0<=k<=j

最後在這裡面找出乙個最大值,然後用v減去max。

var

a,c,sum:array [0..11,0..102] of longint;

b:array [0..11,0..5001] of boolean;

f:array [0..11,0..5001] of longint;

max,i,j,k,l,n,m:longint;

begin

readln(m,n);

for i:=1

to n do

begin

read(a[i,0]);

for j:=1

to a[i,0] do

begin

read(a[i,j]);

sum[i,j]:=sum[i,j-1]+a[i,j];

end;

readln;

end;

for i:=1

to n do

begin

c[i,0]:=1;

for j:=1

to a[i,0] do

for k:=1

to j do

for l:=1

to k do

if sum[i,k]-sum[i,l-1]<=m then

b[i,sum[i,k]-sum[i,l-1]]:=true;

end;

for i:=1

to n do

for j:=0

to m do

begin

f[i,j]:=f[i-1,j];

for k:=0

to j do

if b[i,k] then

if f[i-1,j-k]+k>f[i,j]

then f[i,j]:=f[i-1,j-k]+k;

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

end;

writeln(m-max);

end.

JZOJ1517 揹包問題

這個題,乍一看感覺挺神的 其實真挺神的 其實是個簡單的分組揹包 如果恍然大悟就不用接著看了 取連續的一段是這道題最難以處理的地方,但是觀察到物品數量不多 100 如果恍然大悟就不用接著看了 不妨把連續取物轉化為單個物品,就是說,我們取一段連續物品求和作為乙個物品,這樣,我們只要滿足每組選乙個 或不選...

揹包問題 01揹包問題

n個物品,總體積是v,每個物品的體積的vi,每個物品的最大價值是wi,在不超過v的體積下求最大價值 eg揹包容積為 5 物品數量為 4 物品的體積分別為 物品的價值分別為 思路定義乙個二位陣列int f new int n 1 v 1 f i j 就表示在1 i個物品中選取體積小於v的情況的最大價值...

01揹包問題 完全揹包問題 多重揹包問題

0 1 揹包問題 給定 n 種物品和乙個容量為 c 的揹包,物品 i 的重量是 wi,其價值為 vi 問 應該如何選擇裝入揹包的物品,使得裝入揹包中的物品的總價值最大?分析一波,面對每個物品,我們只有選擇拿取或者不拿兩種選擇,不能選擇裝入某物品的一部分,也不能裝入同一物品多次。解決辦法 宣告乙個 大...