DP优化与换零钱问题
1 当贪心不再起效的时候
对于换零钱问题,最简单也是性能最好的方法就是贪心算法。可是贪心算法一定要满足面值相邻两个零钱至少为二倍关系的前提条件。例如1,2,5,10,20……这样的零钱组应用贪心最简单;可对于1,3,4,5,6,10……这样的零钱组就不起效了:当目标总值是12的时候,应用贪心算法:答案是10x1+1x2,共3张,可正确答案应该是6x2共两张。
那怎么解决呢?这样的问题符合动态规划的特点:任何一个状态可以由前边的状态计算而得。
定义问题(明确需求):一组不重复且升序排列零钱面额数组vector<int> c(共m个元素),目标面值:int n,求所需最少的零钱张数。
2 O(mn)空间复杂度DP算法
就像背包问题。最经典的算法是生成一个(m+1)x(n+1)DP数组来保存中间值,其中dp[i][j]表示只利用第1~i种零钱凑成目标面值为j所需的最少零钱张数。
我们很容易得出状态转移方程:
dp[i][j]=min(0+dp[i-1][j],1+dp[i-1][j-1*c[i]],2+dp[i-1][j-2*c[i]], ······);
从而很容易写出代码。
但作为一个追(xian)求(de)卓(dan)越(teng)的程序员,我又怎么会满足于此?看起来时间复杂度O(mn)已经达到极至,可空间复杂度O(mn)好像可以继续优化!
3 O(n)空间复杂度DP算法
由上边的状态转移方程,我们发现每个元素只用到了上一行的若干个元素。那其实我们很容易想到,一个大小为2*(n+1)的一维数组就足够了!
状态转移方程:
dp[index][j]=min(0+dp[1-index][j],1+dp[1-index][j-1*c[i]],2+dp[1-index][j-2*c[i]], ······);
计算方法没有任何差别,但是空间复杂度却大大降低!
不仅如此,对于有一些DP算法,每个元素的计算只需要用到当前行左边的元素和上一行相同列坐标元素的值(例如矩阵的最小最径的DP算法),这样的算法,我们可以直接用一个n+1的一维数组作为DP数组就够用了!
4 总结
由此,我们可以总结出本文的中心思想:
(1)一个二维DP算法,如果每个元素的计算只需要用到上一行的若干个元素的值的时候,我们都可以用两个一维DP数组来优化空间复杂度。
(2)一个二维DP算法,如果每个元素的计算只需要用到当前行左边的元素和上一行相同列坐标元素的值的时候,我们都可以用一个一维DP数组来优化空间复杂度。
(3)要多尝试降低二维DP算法的空间复杂度。
鼓掌[逃]!
DP优化与换零钱问题的更多相关文章
- 小P的故事——神奇的换零钱&&人活着系列之平方数
http://acm.sdut.edu.cn/sdutoj/showproblem.php?pid=2777&cid=1219 这题不会,看了别人的代码 #include <iostre ...
- 子集和问题(应用--换零钱)POJ2229:Sumsets
我一直在纠结换零钱这一类型的题目,今天好好絮叨一下,可以说他是背包的应用,也可以说他是单纯的dp.暂且称他为dp吧. 先上一道模板题目. sdut2777: 小P的故事——神奇的换零钱 题目描述 已知 ...
- SDUT3145:Integer division 1(换零钱背包)
题目:传送门 题目描述 整数划分是一个非常经典的数学问题. 所谓整数划分,是指把一个正整数n写成为n=m1+m2+...+mi的形式,其中mi为正整数,并且1<=mi<=n,此时,{m1, ...
- 取数字(dp优化)
取数字(dp优化) 给定n个整数\(a_i\),你需要从中选取若干个数,使得它们的和是m的倍数.问有多少种方案.有多个询问,每次询问一个的m对应的答案. \(1\le n\le 200000,1\le ...
- 51nod 1101 换零钱 【完全背包变形/无限件可取】
1101 换零钱 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 收藏 关注 N元钱换为零钱,有多少不同的换法?币值包括1 2 5分,1 2 5角,1 2 5 ...
- 51 Nod 1101 换零钱(动态规划好题)
1101 换零钱 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 收藏 关注 N元钱换为零钱,有多少不同的换法?币值包括1 2 5分,1 2 5角,1 2 5 ...
- [总结]一些 DP 优化方法
目录 注意本文未完结 写在前面 矩阵快速幂优化 前缀和优化 two-pointer 优化 决策单调性对一类 1D/1D DP 的优化 \(w(i,j)\) 只含 \(i\) 和 \(j\) 的项--单 ...
- DP 优化方法大杂烩 & 做题记录 I.
标 * 的是推荐阅读的部分 / 做的题目. 1. 动态 DP(DDP)算法简介 动态动态规划. 以 P4719 为例讲一讲 ddp: 1.1. 树剖解法 如果没有修改操作,那么可以设计出 DP 方案 ...
- DP 优化小技巧
收录一些比较冷门的 DP 优化方法. 1. 树上依赖性背包 树上依赖性背包形如在树上选出若干个物品做背包问题,满足这些物品连通.由于 01 背包,多重背包和完全背包均可以在 \(\mathcal{O} ...
随机推荐
- Visual Studio 2015 开发 ASP.NET 5 有何变化?
本篇博文目录: ASP.NET 5 模版 ASP.NET 5 目录结构 前端管理工具 无编译开发 Microsoft Git Provider 智能感知和错误信息 Smart Unit Testing ...
- publishing failed with multiple errors resource is out of sync with the file system--转
原文地址:http://blog.csdn.net/feng1603/article/details/7398266 今天用eclipse部署项目遇到"publishing failed w ...
- iOS-掌握了时间就掌握了一切!
Demo下载地址 一. NSDate相关知识 1.获取当前时间 [NSDate date]; 注意: 获取的当前时间是世界时间:比我们用的时间慢8个小时. 2.世界时间转化为本地时间 - (void) ...
- 【JUC】JDK1.8源码分析之ConcurrentSkipListMap(二)
一.前言 最近在做项目的同时也在修复之前项目的一些Bug,所以忙得没有时间看源代码,今天都完成得差不多了,所以又开始源码分析之路,也着笔记录下ConcurrentSkipListMap的源码的分析过程 ...
- 在IIS下部署Thinkphp项目,验证码不能显示的解决办法
由于公司租用的是虚拟空间,而且用的是IIS服务器,所以部署PHP的时候就出现很多问题:比如昨天就碰到这个问题:在IIS下部署Thinkphp项目,验证码不能显示 这是生成验证码的方法: // 制作专门 ...
- 【非原创】IOS 验证文字是否是中文
从环信中找到的部分不错的代码,拿出来记录一下 是否是中文 -(BOOL)isChinese{ NSString *match=@"(^[\u4e00-\u9fa5]+$)"; NS ...
- C# DataGridView中指定的单元格不能编辑
注意:DataGridView控件是从.NET Framework 2.0版本开始追加的. ReadOnly属性的使用 DataGridView内所有的单元格不能编辑 当DataGridView.Re ...
- 缓存技术Redis在C#中的使用及Redis的封装
Redis是一款开源的.高性能的键-值存储(key-value store).它常被称作是一款数据结构服务器(data structure server).Redis的键值可以包括字符串(string ...
- Java字节、十进制、十六进制、字符串之间的相互转换
1. 字节转10进制 直接使用(int)类型转换. /* * 字节转10进制 */ public static int byte2Int(byte b){ int r = (int) b; retur ...
- JAVA 链表操作:循环链表
主要分析示例: 一.循环链表简述 二.单链表循环链表 三.双链表循环链表 一.循环链表简述 循环链表即链表形成了一个循环的结构,尾节点不再指向NULL,而是指向头节点HEAD,此时判定链表的结束是尾节 ...