算法:DP(0/1背包)
分析:这道题可用的方法有很多,0/1背包拆解可以,不拆解直接采用完全背包也可以。总之只要凑出m来。
program coins;
const
maxn=25000;
var
n,m,ans,tot:longint;
a,f:array [0..maxn] of longint;
procedure init;
var
i,j,x,y:longint;
begin
readln(n);
for i:=1 to n do
begin
readln(x,y);
for j:=1 to y do
begin
inc(tot);
a[tot]:=x;
end;
end;
readln(m);
end;
function min(x,y:longint):longint;
begin
if x<y then exit(x) else exit(y);
end;
procedure main;
var
i,j:longint;
begin
fillchar(f,sizeof(f),100);{求最小值,初始化为最大值。}
f[0]:=0;
for i:=1 to tot do
begin
for j:=m downto a[i] do
begin
f[j]:=min(f[j],f[j-a[i]]+1);{f[j]表示不用这枚硬币,f[j-a[i]]+1表示用这枚硬币。}
end;
end;
end;
begin
assign(input,'coins.in'); reset(input);
assign(output,'coins.out'); rewrite(output);
init;
main;
if f[m]=f[25000] then writeln(-1) else writeln(f[m]);
close(input); close(output);
end.