题目地址:http://codevs.cn/problem/1047/
分析:
用数组 A 存放当前枚举好的邮票各种面值
DP(A)函数 表示数组A里的邮票面值所能取得的最大的连续的面值;
于是我们深搜要枚举的邮票面值的
上限就为DP(A)+1, 其下限为 前一个枚举的面值加1.即a[step-1]+1;
代码:
type arr=array[0..40] of longint;
var ans,a:arr;
i,n,k,best:longint;
function min(a,b:longint):longint;
begin
if a<b then exit(a)
else exit(b);
end;
function dp(a:arr):longint;
var i,j,t:longint;
f:array[0..600] of longint;
begin
fillchar(f,sizeof(f),$7f);
f[0]:=0;
t:=min(600,a[a[0]]*n);
for i:=1 to t do
begin
for j:=1 to a[0] do
if i>=a[j] then
f[i]:=min(f[i],f[i-a[j]]+1);
if f[i]>n then break;
end;
if i<>(a[a[0]]*n) then dec(i);
exit(i);
end;
procedure dfs(step,max:longint;a:arr);
var i,nmax:longint;
na:arr;
begin
for i:=a[step-1]+1 to max+1 do
begin
na:=a;
na[step]:=i;
na[0]:=step;
nmax:=dp(na);
if step=k then
begin
if nmax>best then
begin
ans:=na;
best:=nmax;
end;
end
else
if step<k then
dfs(step+1,nmax,na);
end;
end;
begin
readln(n,k);
if k=1 then
begin
writeln(1);
writeln('MAX=',n);
halt;
end;
a[0]:=1;a[1]:=1;
dfs(2,n,a);
for i:=1 to k do
write(ans[i],' ');
writeln;
writeln('MAX=',best);
close(input);
close(output);
end.
用数组 A 存放当前枚举好的邮票各种面值
DP(A)函数 表示数组A里的邮票面值所能取得的最大的连续的面值;
于是我们深搜要枚举的邮票面值的
上限就为DP(A)+1, 其下限为 前一个枚举的面值加1.即a[step-1]+1;