[LeetCode](面试题 08.11)硬币
题目
硬币。给定数量不限的硬币,币值为25分、10分、5分和1分,编写代码计算n分有几种表示法。(结果可能会很大,你需要将结果模上1000000007)
示例1:
输入: n = 5输出:2解释: 有两种方式可以凑成总金额:
5=5
5=1+1+1+1+1
示例2:
输入: n = 10输出:4解释: 有四种方式可以凑成总金额:
10=10
10=5+5
10=5+1+1+1+1+1
10=1+1+1+1+1+1+1+1+1+1
说明:
注意:
你可以假设:
- 0 <= n (总金额) <= 1000000
解题思路
1)01背包问题
有N件物品和一个容量为V的背包。第i件物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使价值总和最大。
基本思路:
这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放。令f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值。若只考虑第i件物品的策略(放或不放),那么就可以转化为一个只牵扯前i-1件物品的问题。如果不放第i件物品,那么问题就转化为“前i-1件物品放入容量为v的背包中”,价值为f[i-1][v];如果放第i件物品,那么问题就转化为“前i-1件物品放入剩下的容量为v-c[i]的背包中”,此时能获得的最大价值就是f[i-1][v-c[i]]再加上通过放入第i件物品获得的价值w[i]。
则其状态转移方程为:
f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]}
优化空间复杂度至O(V):
for i=1..Nfor v=V..0f[v]=max{f[v],f[v-c[i]]+w[i]};
注意是以v=V…0的顺序推f[v],这样才能保证推f[v]时f[v-c[i]]保存的是状态f[i-1][v-c[i]]的值。
2)完全背包问题
有N种物品和一个容量为V的背包,每种物品都有无限件可用。第i种物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。其特点是每个物品可以选无数次。
基本思路:
这个问题非常类似于01背包问题,所不同的是每种物品有无限件。也就是从每种物品的角度考虑,与它相关的策略已并非取或不取两种,而是有取0件、取1件、取2件……等很多种。如果仍然按照解01背包时的思路,令f[i][v]表示前i种物品恰放入一个容量为v的背包的最大价值。仍然可以按照每种物品不同的策略写出状态转移方程:
f[i][v]=max{f[i-1][v-k*c[i]]+k*w[i] | 0<=k*c[i]<=v}
01背包问题要按照v=V…0的逆序来循环,这是因为要保证第i次循环中的状态f[i][v]是由状态f[i-1][v-c[i]]递推而来。换句话说,这正是为了保证每件物品只选一次,保证在考虑“选入第i件物品”这件策略时,依据的是一个绝无已经选入第i件物品的子结果f[i-1][v-c[i]]。而现在完全背包的特点恰是每种物品可选无限件,所以在考虑“加选一件第i种物品”这种策略时,却正需要一个可能已选入第i种物品的子结果f[i][v-c[i]],所以就可以并且必须采用v=0…V的顺序循环。
因此,基本思路中的状态转移方程可以等价地变形成这种形式:
f[i][v]=max{f[i-1][v],f[i][v-c[i]]+w[i]}
将这个方程用一维数组实现,便得到了如下的伪代码:
for i=1..Nfor v=0..Vf[v]=max{f[v],f[v-c[i]]+w[i]}
3)对于本题来说,由于硬币个数不限,所以是一个完全背包问题。具体地,我们设置一个 dp 数组来求解
3.1)二维情况:
dp[i][j] 使用前i种硬币计算j分的表示法种数,令coins=[25, 10, 5, 1]
dp[i][j] = dp[i-1][j] + dp[i-1][j-coins[i]] + dp[i-1][j-2*coins[i]] + ... dp[i-1][j-k*coins[i]],其中j>=k*coins[i];
dp[i][j-coins[i]] = dp[i-1][j-coins[i]] + dp[i-1][j-2*coins[i]] + dp[i-1][j-k*coins[i]],其中j>=k*coins[i];
因此,
dp[i][j] = dp[i-1][j] + dp[i][j-coins[i]]
3.2)优化到一维:
dp[k] 表示组成k面额的硬币情况数。
dp[k] = dp[k] + dp[k-coins[i]]
代码
class Solution:def waysToChange(self, n: int) -> int:dp = [0] *(n+1)dp[0] = 1coins = [25, 10, 5, 1]for i in coins:for j in range(i, n+1):dp[j] = dp[j] + dp[j-i]return dp[-1]%1000000007
[LeetCode](面试题 08.11)硬币相关推荐
- LeetCode 面试题 08.11. 硬币 多种解法 完全背包问题
面试题 08.11. 硬币 大家好,我叫亓官劼(qí guān jié ),在CSDN中记录学习的点滴历程,时光荏苒,未来可期,加油~博客地址为:亓官劼的博客 本文原创为亓官劼,请大家支持原创,部 ...
- [Leedcode][JAVA][面试题 08.11][硬币][动态规划]
[问题描述] 面试题 08.11.硬币 硬币.给定数量不限的硬币,币值为25分.10分.5分和1分,编写代码计算n分有几种表示法.(结果可能会很大,你需要将结果模上1000000007)示例1:输入: ...
- 程序员面试金典 - 面试题 08.11. 硬币(背包DP)
文章目录 1. 题目 2. 解题 1. 题目 硬币.给定数量不限的硬币,币值为25分.10分.5分和1分,编写代码计算 n 分有几种表示法.(结果可能会很大,你需要将结果模上1000000007) 示 ...
- 《程序员面试金典(第6版)》 面试题 08.11. 硬币(动态规划,组合问题,C++)
题目描述 硬币.给定数量不限的硬币,币值为25分.10分.5分和1分,编写代码计算n分有几种表示法.(结果可能会很大,你需要将结果模上1000000007) 示例1: 输入: n = 5 输出:2 解 ...
- Leetcode 面试题 08.01. 三步问题
Leetcode 面试题 08.01. 三步问题 1.问题分析 2.问题解决 3.总结 1.问题分析 题目链接:https://leetcode-cn.com/problems/three-steps ...
- LeetCode 面试题 08.01. 三步问题 (动态规划)
面试题 08.01. 三步问题 解法1(动态规划) 分析出递推式:f(n) = f(n - 1) + f(n - 2) + f(n - 3) class Solution {public int wa ...
- [Leetcode] 面试题 08.02. 迷路的机器人
[面试题 08.02. 迷路的机器人] 设想有个机器人坐在一个网格的左上角,网格 r 行 c 列.机器人只能向下或向右移动,但不能走到一些被禁止的网格(有障碍物).设计一种算法,寻找机器人从左上角 ...
- 【面试题 08.11】 硬币(动态规划)
题目 题目链接 硬币.给定数量不限的硬币,币值为25分.10分.5分和1分,编写代码计算n分有几种表示法.(结果可能会很大,你需要将结果模上1000000007) 示例1: 输入: n = 5输出:2 ...
- LeetCode —— 面试题 08.12. 八皇后(Python)
设计一种算法,打印 N 皇后在 N × N 棋盘上的各种摆法,其中每个皇后都不同行.不同列,也不在对角线上.这里的"对角线"指的是所有的对角线,不只是平分整个棋盘的那两条对角线. ...
最新文章
- 各种抠图动态图片_学习抠取动物毛发图片的PS抠图技巧
- java集合类深入分析之TreeMap/TreeSet篇
- python入门有基础-Python入门学习难吗,新手如何学习
- PetaPoco 快速上手
- Makefile_07:Make 的工作方式
- 动态修改属性设置 easyUI
- 实战使用Axure设计App,使用WebStorm开发(4) – 实现页面UI
- 使用jQuery Mobile快速开发手机站点
- 为什么被喷的总是产品经理?
- Barcode for Mac(条形码生成器)
- matlab把结构按条件排序,matlab结构体数组排序
- Cameralink转HDMI接口转换模块
- WinForGIFSicle 1.0.0.1 免费开源版,基于GIFSicle的开源可视化批量GIF压缩工具
- Python 数据分析微专业课程--项目实战09 房价影响因素挖掘1.项目说明2.项目具体要求3.实现思路:4.实现过程:5.结论:
- 单片机学习(三)中断
- mysql中的查找算法_7种查找算法解析
- word打开出现乱码要如何解决呢?
- AI 图像识别的测试
- python导入keras_无法从keras.models python导入名称Cop
- 一张图学Python