算法:DP
分析:前两种情况好解决,用个背包可以轻松搞定,看f[m]是否=0或者是否>1,这两种情况都是无解的。
然后就是记录路径了,再开一个数组,记录每个容量的背包下的选择。最后输出一下即可。{记录的是编号,无需快排……}
program Vijos1071;
const
maxn=100;
maxw=10000;
var
n,m:longint;
f,w:array [0..maxw] of longint;
a:array [0..maxn] of longint;
b:array [0..maxn] of boolean;
procedure init;
var
i:longint;
begin
readln(m);
readln(n);
for i:=1 to n do readln(a[i]);
end;
procedure main;
var
i,j:longint;
begin
f[0]:=1;
for i:=1 to n do
begin
for j:=m downto a[i] do
begin
if f[j-a[i]]>0 then
begin
inc(f[j],f[j-a[i]]);
if f[j]=1 then w[j]:=i;{这里a[]是有序的,因此第一次确定的f[j]就是这条路径上的一个确定的选择。}
end;
end;
end;
end;
procedure outit;
var
i,t,rest:longint;
begin
if f[m]=0 then
begin
writeln(0);
close(input);
close(output);
halt;
end;
if f[m]>1 then
begin
writeln(-1);
close(input);
close(output);
halt;
end;
{输出。}
t:=w[m];
rest:=m;
while t>0 do
begin
b[t]:=true;
dec(rest,a[t]);
t:=w[rest];
end;
for i:=1 to n do if not b[i] then write(i,' ');
writeln;
end;
begin
assign(input,'VJ1071.in'); reset(input);
assign(output,'VJ1071.out'); rewrite(output);
init;
main;
outit;
close(input); close(output);
end.