Codevs P1047 邮票面值设计
题目描述 Description
给定一个信封,最多只允许粘贴N张邮票,计算在给定K(N+K≤40)种邮票的情况下(假定所有的邮票数量都足够),如何设计邮票的面值,能得到最大值MAX,使在1~MAX之间的每一个邮资值都能得到。
例如,N=3,K=2,如果面值分别为1分、4分,则在1分~6分之间的每一个邮资值都能得到(当然还有8分、9分和12分);如果面值分别为1分、3分,则在1分~7分之间的每一个邮资值都能得到。可以验证当N=3,K=2时,7分就是可以得到的连续的邮资最大值,所以MAX=7,面值分别为1分、3分。
输入输出
输入描述 Input Description
N和K
输出描述 Output Description
每种邮票的面值,连续最大能到的面值数。数据保证答案唯一。
样例 Sample
样例输入 Sample Input
3 2
样例输出 Sample Output
1 3
MAX=7
数据范围及提示 Data Size & Hint
代码如下
program p1047;
var n,k,i,maxn:longint;
num,ans:array[1..1000] of longint;
f:array[0..1000] of longint;
function max(a,b:longint):longint;
var i:longint;
begin
if a>b then exit(a);
for i:=1 to k do
ans[i]:=num[i];
exit(b);
end;
function min(a,b:longint):longint;
begin
if a<b then exit(a);
exit(b);
end;
procedure dp;
var i,j:longint;
begin
i:=0;
f[0]:=0;
repeat
inc(i);
f[i]:=maxlongint;
for j:=1 to k do
begin
if i-num[j]>=0
then
begin
f[i]:=min(f[i],f[i-num[j]]+1);
end;
end;
until f[i]>n;
maxn:=max(maxn,i-1);
end;
procedure dfs(step:longint);
var i:longint;
begin
for i:=num[step-1]+1 to n*num[step-1]+1 do
begin
num[step]:=i;
if step<k
then
begin
dfs(step+1);
end
else dp;
end;
end;
begin
readln(n,k);
num[1]:=1;
maxn:=-maxlongint;
dfs(2);
for i:=1 to k do
write(ans[i],' ');
writeln;
write('MAX=',maxn);
end.
评测结果
测试通过 Accepted
总耗时: 672 ms
0 / 0 数据通过测试.
运行结果
测试点#stamp1.in 结果:AC 内存使用量: 268kB 时间使用量: 1ms
测试点#stamp2.in 结果:AC 内存使用量: 128kB 时间使用量: 37ms
测试点#stamp3.in 结果:AC 内存使用量: 256kB 时间使用量: 3ms
测试点#stamp4.in 结果:AC 内存使用量: 168kB 时间使用量: 631ms