(连续邮资问题)某国发行了 n 种不同面值的邮票,并规
(连续邮资问题)某国发行了 n 种不同面值的邮票,并规定每封信最多允许贴 m 张邮票,在这 些约束下,为了能贴出 {1 , 2,3, …,maxvalue} 连续整数集合的所有邮资,并使 maxvalue 的值最 大,应该如何设计各邮票的面值?例如,当 n=5 、m=4 时,面值设计为 {1 , 3,11 ,15 ,32} ,可使 maxvalue 达到最大值 70 (或者说,用这些面值的 1 至4 张邮票可以表示不超过 70 的所有邮资,但无 法表示邮资 71 。而用其他面值的 1 至4 张邮票如果可以表示不超过 k 的所有邮资,必有 k ≤70 )。
下面是用递归回溯求解连续邮资问题的程序。数组 x[1:n] 表示 n 种不同的邮票面值,并约定各元 素按下标是严格递增的。数组 bestx[1:n] 存放使 maxvalue 达到最大值的邮票面值(最优解), 数组 y[maxl] 用于记录当前已选定的邮票面值 x[1:i] 能贴出的各种邮资所需的最少邮票张数。请将程 序补充完整。
#include<stdio.h>
#defineNN20
#definemaxint30000
#definemaxl500/* 邮资的最大值 */
int n,m,bestx[NN],x[NN],y[maxl],maxvalue=0;
void result()
{
输出结果:最大值: maxvalue 及 最优解: bestx[1:n] (略)
}
void backtrace(inti,intr)
{
int j,k,z[maxl];
for(j=0;j<= ① ;j++)
if(y[j]<m)
for(k=1;k<=m-y[j];k++)
if(y[j]+k<=y[ ② ])
y[ ③ ]=y[j]+k;
while(y[r]<maxint)r++;
if(i>n)
{
if(r-1>maxvalue)
{
maxvalue= ④ ;
for(j=1;j<=n;j++)
bestx[j]=x[j];
}
return;
}
for(k=0;k<maxl;k++)
z[k]=y[k];
for(j= ⑤ ;j<=r;j++)
{
x[i]=j;
⑥ ;
for(k=0;k<maxl;k++)
y[k]=z[k];
}
}
void main()
{
int j;
printf("inputn,m:\n");
scanf( "%d%d",&n,&m);
for(j=1;j<maxl;j++)
y[j]=maxint;
y[0]=0;x[0]=0;x[1]=1;
backtrace(2,1);
result();
}答案
第1空:x[i-2]*(m-1)
第2空:j+x[i-1]*k
第3空:j+x[i-1]*k
第4空:r-1
第5空:x[i-1]+1
第6空:backtrace(i+1,r)