邮票问题

Problem Description

设有已知面额的邮票m种,每种有n张,用总数不超过n张的邮票,能从面额1开始,最多连续组成多少面额。(1≤m≤100,1≤n≤100,1≤邮票面额≤255)

INPUT

第一行:m,n的值,中间用一空格隔开。

第二行:A[1..m](面额),每个数中间用一空格隔开。

OUTPUT

连续面额数的最大值

Sample Input

3 4

1 2 4

Sample Output

14

分析

最容易想到的方法是从面额i=1开始计算最少张数,逐渐增加,直到所计算出的张数大于n。最大面额为255,n的最大值为100,所以最大面额不超过25500。意味着最坏情况下需要循环2x104次才能完成,因此算法的效率主要就取决于如何计算构成面额i所需要的最少张数。以三种思路来分析:

  • 用i每次减去m种邮票中面值小于等于i的最大面值,计算减去多少次后等于0。这种思路正确吗?举个反例:有1, 5, 10, 20, 28, 50共6种邮票,现在要构造面值56,按照思路1,是这样的:56-50=6, 6-5=1, 1-1=0,共需要1, 5, 50三张邮票。但你其实可以发现:56-28=28,用两张28便可构成。这证明该思路不正确。
  • 使用递推方法:面额i的最小张数mz[i]=mz[j]+mz[i-j],举个例子:20元可以分为1+19,1元所需要的最小张数加上19元所需要的最小张数就是20元的张数,这次分解得到的值不一定是最小的,需要把所有分解方法枚举一遍:mz[1]+mz[19], mz[2]+mz[18], ..., mz[9]+mz[11], mz[10]+mz[10],枚举的个数为i/2个。最终要的结果为:mz[20]=min{mz[1]+mz[19], mz[2]+mz[18], ..., mz[10]+mz[10]}。这个方法一定无误,问题在于时间复杂度O(n)=i*i/2,时间复杂度可达108,难免会超时,还需要改进。
  • 在思路2的基础上如何改进呢?关键在于分解方法低效,一元一元分解并无意义,完全可以按照m种邮票的面额进行分解。例如有1, 5, 10, 20, 28, 50共6种邮票,现在要构造面值56,可以这样分解:mz[56]=min{mz[1]+mz[55], mz[5]+mz[51], mz[10]+mz[46], mz[20]+mz[36], mz[28]+mz[28], mz[50]+mz[6]}。照这样分解最多需要m次,该方法同样无误,但可以把时间复杂度降低两个数量级至106

递推的起点是什么?已有的m种邮票面额yp[j] (j=1...m)所需要的张数mz[yp[j]]=1 (j=1...m),这就是递推的起点,需要的已知条件。

代码示例

#include<iostream>
using namespace std;
int yp[256]; //邮票面额,不使用yp[0]
int mz[25601]; //所有面值需要的最少张数,连续面额个数不超256*100
int main(){
int m, n, i=1; //变量i为要计算张数的面额
scanf("%d%d", &m, &n);
for(int i=1; i<=m; i++){
scanf("%d", &yp[i]); //存储该面额
mz[yp[i]]=1; //该面额只需要1张,亦为递推的临界值
}
while(1){ //i从1开始分析
for(int j=1; j<=m; j++){ //递推规则
if(i>=yp[j]){
int zs=mz[yp[j]]+mz[i-yp[j]];
if(mz[i]==0) mz[i]=zs;
else if(zs<mz[i]) mz[i]=zs;
}
}
//printf("%d->%d\n", i, mz[i]);调试使用
if(mz[i]>n || mz[i]==0) break; //超出n张邮票
i++;
}
printf("%d", i-1); //输出最大连续面额
return 0;
}

LFYZ-OJ ID: 1021 邮票问题的更多相关文章

  1. 九度OJ 1209 最小邮票数 -- 动态规划

    题目地址:http://ac.jobdu.com/problem.php?pid=1209 题目描述: 有若干张邮票,要求从中选取最少的邮票张数凑成一个给定的总值.     如,有1分,3分,3分,3 ...

  2. 九度oj 题目1021:统计字符

    题目描述:     统计一个给定字符串中指定的字符出现的次数. 输入:     测试输入包含若干测试用例,每个测试用例包含2行,第1行为一个长度不超过5的字符串,第2行为一个长度不超过80的字符串.注 ...

  3. 【BZOJ 1021】[SHOI2008]Debt 循环的债务

    [题目链接]:http://www.lydsy.com/JudgeOnline/problem.php?id=1021 [题意] [题解] 设f[i][j][k]表示前i种面值的钱币; 第一个人当前的 ...

  4. dom4j修改,获取,增加xml中某个元素的属性值

    XML文件: <?xml version="1.0" encoding="UTF-8"?> <vrvscript> <item I ...

  5. BZOJ_1021_[SHOI2008]_Debt循环的债务_(DP)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1021 三个人相互欠钱,给出他们每个人各种面额的钞票各有多少张,求最少需要传递多少张钞票才能把账 ...

  6. [JS]省市区数据及方法调用

    调用方法: function GetProvinceByid(id) { if (id == null || id == undefined || id == "") return ...

  7. 解决Javascript大数据列表引起的网页加载慢/卡死问题。

    在一些网页应用中,有时会碰到一个超级巨大的列表,成千上万行,这时大部份浏览器解析起来就非常痛苦了(有可能直接卡死). 也许你们会说可以分页或动态加载啊?但是有可能需求不允许分页,动态加载?网络的延迟也 ...

  8. bootstrap-treeview分级展示列表树的实现

    html页面: 要引用 "/webapp/common/css/bootstrap-treeview.css" "/webapp/common/js/bootstrap- ...

  9. 反编译 轻松调频 Android APP 下载“飞鱼秀”录音

    经常听“飞鱼秀”,但是由于时间的原因,只能听回放,但是轻松调频的APP做的有点儿... 听回放的时候经常会中断,还不能拖动进度条,就决定把录音下载下来听. 1.反编译apk(Android反编译过程见 ...

随机推荐

  1. web渗透 学习计划(转载)

    作者:向生李链接:https://www.zhihu.com/question/21914899/answer/39344435来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明 ...

  2. Selenium自动化测试-unittest单元测试框架使用

    一.什么是unittest 这里我们将要用的unittest是python的单元测试框架,它的官网是 https://docs.python.org/2/library/unittest.html,在 ...

  3. 记录Vim常用命令

    命令 简单说明 i 进入编辑模式,光标在原位置 I 进入编辑模式,光标在行首位置 o 从光标所在行,下面一行开始编辑 O 从光标所在行,上面一行开始编辑 a 从光标当前字符后编辑 A 从光标所在行的行 ...

  4. 日志学习系列(三)——NLog基础知识

    前边我们解释了log4net的学习,我们再介绍一下NLog 一.什么是NLog NLog是一个基于.NET平台编写的类库,我们可以使用NLog在应用程序中添加极为完善的跟踪调试代码.NLog是一个简单 ...

  5. LeetCode练习4 找出这两个有序数组的中位数

    给定两个大小为 m 和 n 的有序数组 nums1 和 nums2. 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n)). 你可以假设 nums1 和 nums2  ...

  6. C++ shared_ptr、unique_ptr、weak_ptr

    shared_ptr unique_ptr weak_ptr 内存泄漏 智能指针 引用计数 循环引用 reset

  7. 采用ADM2483磁隔离器让RS485接口更简单更安全

    采用ADM2483磁隔离器让RS485接口更简单更安全 摘要:本文介绍RS485的特点及应用,指出了普通RS485接口易损坏的问题,针对存在的问题介绍了以ADM2483为核心的磁隔离解决方案. 关键词 ...

  8. Java面试准备之多线程

    什么叫线程安全?举例说明 多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些线程将如何交替执行,并且在主调代码中不需要任何额外的同步或者协同,这个类都能表现出正确的行为,那么就称这个类是线程 ...

  9. TypeError: sequence item 1: expected str instance, int found

    Error Msg Traceback (most recent call last): File "E:/code/adva_code/my_orm.py", line 108, ...

  10. js字符串轉數組,數組轉字符串

    字符串轉數組:split(',') 數組轉字符串:join(‘,’) https://www.cnblogs.com/woodk/p/5714329.html