Description
从T组物品中选出一些物品,放入背包中,求剩余空间的最小值。
限制条件:从每组物品中挑选物品必须要选取连续的一段。就是说,如果这组物品共有n个: 物品1、物品2、物品3、…、物品n,那么只能选取物品i、物品i+1、…、物品j,其中1<=i<=j<=n,或者不选。
Input
第一行为两个用空格隔开的正整数v和T。表示背包的空间和物品的组数。接下来有T行,每行先是一个正整数ni,表示这组物品有ni个,然后ni个正整数,表示每个物品的大小。
Output
仅一个数,表示剩余空间的最小值。
Sample Input
100 3
3 7 6 8
2 80 70
4 101 108 103 150
Sample Output
6
Hint
【样例说明】
第1组选6、8,第2组选80,第3组不选。
【限制】
60%的数据满足:1 <= ni <= 10
100%的数据满足:1 <= ni <= 100,1<=v<=5000,1<=T<=10
算法讨论
f[x]表示是否存在x体积的方案,枚举每组的连续区间的左右端点,在背包范围内即存在。
var
i,j,k,l,v,t:longint;
s:array[1..20] of longint;
f,q:array[0..20,0..200] of longint;
c:array[0..6000] of boolean;
begin
readln(v,t);
for i:=1 to t do
begin
read(s[i]);
for j:=1 to s[i] do
begin
read(f[i,j]);
if f[i,j]=v then
begin
writeln(0);
exit;
end;
q[i,j]:=q[i,j-1]+f[i,j];
end;
end;
c[0]:=true;
for i:=1 to t do
for j:=v downto 0 do
if c[j] then
for k:=1 to s[i] do
for l:=k downto 0 do
if j+q[i,k]-q[i,l]<=v then
c[j+q[i,k]-q[i,l]]:=true
else break;
for i:=v downto 0 do
if c[i] then
begin
writeln(v-i);
exit;
end;
end.