Ø假设国家发行了n种不同面值的邮票,并且
规定每张信封上最多只允许贴m张邮票。连
续
邮资问题要求对于给定的n和m的值,给出
邮票面值的最佳设计,在1张信封上可贴出
从邮资1开始,增量为1的最大连续邮资区
间。(NOIP99)
Ø例如,当n=2、m=3时,如果面值分别为1
、4,则在l-6之间的每一个邮资值都能得到(当
然还有8、9和12);如果面值分别为1、3,则
在1-7之间的每一个邮资值都能得到。可以
验证当n=2、m=3时,7就是可以得到连续的邮
资最大值,面值为l、3。
Ø又如,当n=5和m=4时,面值为(1,3,11,15,32)
的5种邮票可以贴出邮资的最大连续邮资区
间是1到70。
Ø基本思路:搜索所有可行解,找出最大连续邮资区间的方案
Ø解向量:用n元组x[1:n]表示n种不同的邮票面值,并约定它们从小到大排列。x[1]=1是唯一的选择。
Ø可行性约束函数:已选定x[1:i-1],最大连续邮资区间是1—r,接下来x[i]的可取值范围是x[i-1]+1—r+1。
Ø如何确定r的值:计算X[1:i]的最大连续邮资区间在本算法中被频繁使用到,因此势必要找到一个高效的方法。考虑到直接递归的求解复杂度太高,我们不妨尝试计算用不超过m张面值为x[1:i]的邮票贴出邮资k所需的最少邮票数y[k]。通过y[k]可以很快推出r的值。事实上,y[k]可以通过递推在O(n)时间内解决:
for (int j=0; j<= x[i-2]*(m-1);j++)
if (y[j]<m)
for (int k=1;k<=m-y[j];k++)
if (y[j]+k<y[j+x[i-1]*k]) y[j+x[i-1]*k]=y[j]+k;
while (y[r]<maxint) r++;