算法:DP+搜索
分析:解决这到题的思路还是比较清晰的。
先快排一下,保证集合最小,再从集合的规模上面先从小到大枚举一下,然后利用DFS选出组成牛奶的箱子种类,最后用选出来的箱子种类做一次完全背包,如果能组成牛奶量,那么它一定是最优的。
分析:解决这到题的思路还是比较清晰的。
先快排一下,保证集合最小,再从集合的规模上面先从小到大枚举一下,然后利用DFS选出组成牛奶的箱子种类,最后用选出来的箱子种类做一次完全背包,如果能组成牛奶量,那么它一定是最优的。
{
ID:1011mashuo
PROG:milk4
LANG:PASCAL
}
program milk4;
const
maxn=100;
maxm=30000;
var
n,m:longint;
a,b:array [0..maxn] of longint;
procedure init;
var
i:longint;
begin
readln(m);
readln(n);
for i:=1 to n do readln(a[i]);
end;
procedure qsort(l,r:longint);
var
i,j,m,t:longint;
begin
i:=l;
j:=r;
m:=a[(l+r) shr 1];
repeat
while a[i]<m do inc(i);
while a[j]>m do dec(j);
if i<=j then
begin
t:=a[i];
a[i]:=a[j];
a[j]:=t;
inc(i);
dec(j);
end;
until i>j;
if i<r then qsort(i,r);
if l<j then qsort(l,j);
end;
procedure print(x:longint);
var
i:longint;
begin
write(x,' ');
for i:=1 to x-1 do write(b[i],' ');
writeln(b[x]);
close(input);
close(output);
halt;
end;
procedure beibao(x:longint);
var
i,k:longint;
f:array [0..maxm] of boolean;
begin
fillchar(f,sizeof(f),false);
k:=0;
f[0]:=true;
while k<m do
begin
if f[k] then
begin
for i:=1 to x do
begin
f[k+b[i]]:=true;
if k+b[i]=m then print(x);
end;
end;
inc(k);
end;
end;
procedure dfs(dep,st,mdep:longint);
var
i:longint;
begin
if dep>mdep then
begin
beibao(mdep);
exit;
end;
for i:=st to n do
begin
b[dep]:=a[i];
dfs(dep+1,i+1,mdep);
end;
end;
procedure main;
var
i:longint;
begin
for i:=1 to n do dfs(1,1,i);
end;
begin
assign(input,'milk4.in'); reset(input);
assign(output,'milk4.out'); rewrite(output);
init;
qsort(1,n);
main;
close(input); close(output);
end.