題目大意:
從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 問 應該如何選擇裝入揹包的物品,使得裝入揹包中的物品的總價值最大?分析一波,面對每個物品,我們只有選擇拿取或者不拿兩種選擇,不能選擇裝入某物品的一部分,也不能裝入同一物品多次。解決辦法 宣告乙個 大...