当前位置:网站首页>动态规划、背包问题 6/22 96-100
动态规划、背包问题 6/22 96-100
2022-08-10 05:36:00 【吉良吉影__.】
1.爬楼梯( LeetCode 70 )动态规划
方法一:递归 (超时)
class Solution {
int ans;
public int climbStairs(int n) {
dfs(0,n);
return ans;
}
public void dfs(int i,int n){
if (i > n)return;
if (i == n)ans++;
dfs(i + 1,n);
dfs(i + 2,n);
}
}
方法二:动态规划
多想几个用例,看看是否存在规律
class Solution {
public int climbStairs(int n) {
if (n < 3) return n;
//dp[i] 爬到第i级楼梯的方案数
int[] dp = new int[n + 1];
dp[1] = 1;
dp[2] = 2;
for (int i = 3; i <= n; i++) {
dp[i] = dp[i - 1] + dp[i - 2];
}
return dp[n];
}
}
方法三:
使用滚动数组思想对方法二优化
class Solution {
public int climbStairs(int n) {
if (n < 3) return n;
int p = 1;
int q = 2;
int r = 0;
for (int i = 3; i <= n; i++) {
r = p + q;
p = q;
q = r;
}
return r;
}
}
2.最大子数组和( LeetCode 53 )
动态规划
class Solution {
public int maxSubArray(int[] nums) {
//dp[i] 已第i个数结尾的最大子数组和
int[] dp = new int[nums.length];
dp[0] = nums[0];
int ans = dp[0];
for (int i = 1; i < nums.length; i++) {
dp[i] = Math.max(dp[i - 1] + nums[i],nums[i]);
if (dp[i] > ans)ans = dp[i];
}
return ans;
}
}
3.零钱兑换( LeetCode 322 )
方法一:记忆化数组
分治思想,把大问题分解为小问题
记忆化数组,存储已经计算过的数值,当再次遇到相同数值时不用重复计算
public class Solution {
public int coinChange(int[] coins, int amount) {
// 初始条件检查
if (amount < 1) return 0;
// 动态规划入口
return coinChange(coins, amount, new int[amount]);
}
/** * 自上而下的动态规划方法 * coins:硬币面额 * rem:余额 * count:存储中间计算结果,空间换时间,count为记忆化数组,空间换时间 */
private int coinChange(int[] coins, int rem, int[] count) {
// 结束条件:此路径不通
if (rem < 0) return -1;
// 结束条件:余额为0,成功结束
if (rem == 0) return 0;
// 之前已经计算过这种情况,直接返回结果,避免重复计算
if (count[rem - 1] != 0) return count[rem - 1];
int min = Integer.MAX_VALUE;
// 遍历当前递归子树的每一种情况
for (int coin : coins) {
// 用一下coin这个面值的硬币会怎样?res是这个方法的最优情况
int res = coinChange(coins, rem - coin, count);
// res<0 即为 res=-1,此法失败,res>min不是最优情况,舍去
if (res >= 0 && res < min)
min = 1 + res;
}
// count[rem - 1]存储着给定金额amount的解
// 若为Integer.MAX_VALUE则该情况无解
count[rem - 1] = (min == Integer.MAX_VALUE) ? -1 : min;
return count[rem - 1];
}
}
方法二:动态规划
完全背包 朴素数组
class Solution {
public int coinChange(int[] coins, int amount) {
if (amount == 0)return 0;
int[][] dp = new int[coins.length][amount + 1];
for (int i = 0; i <= amount; i++) {
int k = i / coins[0];
if (k * coins[0] == i)dp[0][i] = k;
else dp[0][i] = -1;
}
for (int i = 1; i < coins.length; i++) {
int coin = coins[i];
for (int j = 0; j <= amount; j++) {
//不选本枚硬币
int x = dp[i - 1][j];
//选本枚硬币
int y = Integer.MAX_VALUE;//y = Integer.MAX_VALUE时代表不能选择本枚硬币
for (int k = 1; ; k++) {
if (k * coin > j)break;
int z = dp[i - 1][j - k * coin];
y = Math.min(y,z == -1 ? Integer.MAX_VALUE : z + k);
}
if (x == -1){
dp[i][j] = y == Integer.MAX_VALUE ? -1 : y;
}else {
dp[i][j] = Math.min(x,y);
}
}
}
return dp[coins.length - 1][amount];
}
}
方法三:
完全背包 一维数组
class Solution {
public int coinChange(int[] coins, int amount) {
if (amount == 0)return 0;
int[] dp = new int[amount + 1];
for (int i = 0; i <= amount; i++) {
int k = i / coins[0];
if (k * coins[0] == i)dp[i] = k;
else dp[i] = -1;
}
for (int i = 1; i < coins.length; i++) {
int coin = coins[i];
for (int j = 0; j <= amount; j++) {
//不选本枚硬币
int x = dp[j];
//选本枚硬币
int y = Integer.MAX_VALUE;//y = Integer.MAX_VALUE时代表不能选择本枚硬币
if (j - coin >= 0 && dp[j - coin] != -1){
y = dp[j - coin] + 1;
}
if (x == -1){
dp[j] = y == Integer.MAX_VALUE ? -1 : y;
}else {
dp[j] = Math.min(x,y);
}
}
}
return dp[amount];
}
}
4.零钱兑换 II( LeetCode 518 )
官方解:动态规划
//动态规划
class Solution {
public int change(int amount, int[] coins) {
int[] dp = new int[amount + 1];
dp[0] = 1;
//外层遍历coins,保证了硬币放入的顺序
//比如coins = 1,2 amount = 1时
//先出现的一定是 1 1,然后才是2 2
for (int coin : coins) {
for (int i = coin; i <= amount; i++) {
dp[i] += dp[i - coin];
}
}
return dp[amount];
}
}
解法二:
完全背包 朴素数组
class Solution {
public int change(int amount, int[] coins) {
//dp[i][j] 前i个数中选择凑成金额j的方案数
int[][] dp = new int[coins.length][amount + 1];
for (int i = 0; i <= amount; i++) {
//i % coins[0] == 0代表第一枚硬币可以凑出金额i
dp[0][i] = (i % coins[0] == 0) ? 1 : 0;
}
for (int i = 1; i < coins.length; i++) {
int coin = coins[i];
for (int j = 0; j <= amount; j++) {
dp[i][j] = dp[i - 1][j];//不选coin的方案数
for (int k = 1;; k++) {
//选coin的方案数
if (k * coin > j)break;
dp[i][j] += dp[i - 1][j - k * coin];//加上选k枚硬币的方案数
}
}
}
return dp[coins.length - 1][amount];
}
}
方法三:
完全背包 一维数组
class Solution {
public int change(int amount, int[] coins) {
//dp[i][j] 前i个数中选择凑成金额j的方案数
int[] dp = new int[amount + 1];
//初始化
for (int i = 0; i <= amount; i++) {
dp[i] = i % coins[0] == 0 ? 1 : 0;
}
for (int i = 1; i < coins.length; i++) {
int coin = coins[i];
for (int j = 0; j <= amount; j++) {
if (j - coin >= 0){
dp[j] += dp[j - coin];
}
}
}
return dp[amount];
}
}
5.最小路径和( LeetCode 64 )
动态规划
class Solution {
public int minPathSum(int[][] grid) {
int[][][] dp = new int[grid.length][grid[0].length][2];
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
dp[i][j][0] = Integer.MAX_VALUE;
dp[i][j][1] = Integer.MAX_VALUE;
}
}
//dp[i][j][0] 上一个元素在左边
//dp[i][j][1] 上一个元素在上边
dp[0][0][0] = grid[0][0];
//初始化dp第一行
for (int i = 1; i < grid[0].length; i++) {
dp[0][i][0] = grid[0][i] + dp[0][i - 1][0];
}
//初始化dp第一列
dp[0][0][1] = grid[0][0];
for (int i = 1; i < grid.length; i++) {
dp[i][0][1] = grid[i][0] + dp[i - 1][0][1];
}
for (int i = 1; i < grid.length; i++) {
for (int j = 1; j < grid[0].length; j++) {
//上一个元素在左边
dp[i][j][0] = Math.min(dp[i][j - 1][0],dp[i][j - 1][1]) + grid[i][j];
//上一个元素在上面
dp[i][j][1] = Math.min(dp[i - 1][j][0],dp[i - 1][j][1]) + grid[i][j];
}
}
return Math.min(dp[grid.length - 1][grid[0].length - 1][0]
,dp[grid.length - 1][grid[0].length - 1][1]);
}
}
边栏推荐
- 以STM32F103C6T6为例通过配置CubeMX实现EXIT外部中断
- 视差映射:更逼真的纹理细节表现(上):为什么要使用视差映射
- Pytorch - 07. Multidimensional characteristics of input processing
- 每日刷题(day03)——leetcode 899. 有序队列
- mysql使用常见问题和解决
- STM32单片机OLED俄罗斯方块单片机小游戏
- LruCache与DiskLruCache结合简单实现ImageLoader
- 51单片机智能远程遥控温控PWM电风扇系统红外遥控温度速度定时关机
- LeetCode refers to the offer 21. Adjust the order of the array so that the odd numbers are in front of the even numbers (simple)
- STM32F407ZG TIM通用定时器
猜你喜欢
新建STM32F407ZG Keil5项目
Pico设备中的截图以及视频文件通过adb命令保存到电脑中
【图像识别】训练一个最最简单的AI使其识别Vtuber
STM32单片机手机APP蓝牙高亮RGB彩灯控制板任意颜色亮度调光
Unity中Xml简介以及通过脚本读取Xml文本中的内容
pytorch-11. Convolutional Neural Network (Advanced)
STM32单片机LORA无线远程火灾报警监控系统DS18B20MQ2火焰检测
LeetCode 2011.执行操作后的变量值(简单)
LeetCode refers to the offer 21. Adjust the order of the array so that the odd numbers are in front of the even numbers (simple)
序列化、编码、requests库json和data参数
随机推荐
每日刷题(day02)——leetcode 622. 设计循环队列
Notes for Netual Network
在Unity中让物体围绕自身的x、y、z轴进行旋转(亲测有效)
Notes for RNN
手机端应用类型
详解 Hough 变换(上)基本原理与直线检测
STM32单片机LORA无线远程火灾报警监控系统DS18B20MQ2火焰检测
除砷树脂吸附原理
解析树字符串并输出中序遍历
每日刷题(day03)——leetcode 899. 有序队列
LeetCode 94. Inorder Traversal of Binary Trees (Simple)
三种素数筛总结——(朴素筛,埃氏筛,线性筛)
详解样条曲线(上)(包含贝塞尔曲线)
(Flutter报错)Cannot run with sound null safety, because the following dependencies
内核性能分析总结
多线程与多进程(概念详细讲解)
Gradle学习 (一) 入门
Explain the principle of MySql index in detail
Machine Learning - Clustering - Shopping Mall Customer Clustering
STM32F407ZG 看门狗 IWDG & WWDG