力扣爆刷第128天之动态规划五连刷(一个零、零钱兑换、组合)

本文主要是介绍力扣爆刷第128天之动态规划五连刷(一个零、零钱兑换、组合),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

力扣爆刷第128天之动态规划五连刷(一个零、零钱兑换、组合)

文章目录

      • 力扣爆刷第128天之动态规划五连刷(一个零、零钱兑换、组合)
      • 终结背包问题:这篇文章和上一篇。
      • 动态规划解题步骤:
      • 背包问题总结
      • 一、474. 一和零
      • 二、518. 零钱兑换 II
      • 三、377. 组合总和 Ⅳ
      • 四、57. 爬楼梯(第八期模拟笔试)
      • 五、322. 零钱兑换

终结背包问题:这篇文章和上一篇。

动态规划解题步骤:

  1. 确定dp数组(dp table)以及下标的含义。
  2. 确定递推公式。
  3. dp数组如何初始化。
  4. 确定遍历顺序。
  5. 举例推导dp数组。

背包问题总结

背包问题:一维数组,dp[j] = Math.max(dp[j], dp[j-nums[i]] + nums[i])。

01背包遍历顺序: 先物品后背包,物品正序,背包逆序。

如若背包正序则会出现同一个物品重复放入,如物品1重量为1,背包空间为1时放入了,背包空间为2时又放入了。
如果先背包后物品,为了避免重复放入背包依然是逆序,背包容量固定时,每种背包容量只能放入一个物品,即为最大的物品,小的物品都放不进来或者被覆盖了。

求组合数排列数:dp[j] += dp[j - nums[i]]

完全背包遍历顺序: 物品背包没有先后顺序,物品背包都是正序。因为同一个物品不限量可以放入多次,在背包采用正序中。

完全背包求组合数,物品在外,背包在内。求排列数,背包在外,物品在内。

一、474. 一和零

题目链接:https://leetcode.cn/problems/ones-and-zeroes/description/
思路:一和零是双重背包,本质上还是0 1 背包,只不过现在背包的容量有两个指标,所以还是0 1背包的套路,定义dp[i][j]数组表示容量为i个0和j个1的背包最多可以装下的字符串数量,故当前背包装物品的数量依赖于上一个容量较小时装的数量,具体是多少容量呢,当然是可以满足装下最大数量的容量,那到底是什么呢,就是例如有一个字符串有2个0和3个1,依赖于dp数组的定义,想让当前空间利用率最大,自然是把空间都占满,dp[i][j] = dp[i-2][j-3] + 1。故递推公式为dp[i][j] = Math.max(dp[i][j], dp[i-nums[0]][j-nums[1]] + 1);

class Solution {public int findMaxForm(String[] strs, int m, int n) {int[][] dp = new int[m+1][n+1];for(String s : strs) {int[] nums = countNums(s);for(int i = m; i >= nums[0]; i--) {for(int j = n; j >= nums[1]; j--) {dp[i][j] = Math.max(dp[i][j], dp[i-nums[0]][j-nums[1]] + 1);}}}return dp[m][n];}int[] countNums(String s) {int[] nums = new int[2];int a = 0, b = 0;for(int i = 0; i < s.length(); i++) {if(s.charAt(i) == '0') {a++;}else{b++;}}nums[0] = a;nums[1] = b;return nums;}
}

二、518. 零钱兑换 II

题目链接:https://leetcode.cn/problems/coin-change-ii/description/
思路:本题物品数量无限是完全背包,完全背包求组合数。完全背包物品和背包都是正序,如果求组合数,物品在外,背包在内。如果求排列数,背包在外,物品在内。

class Solution {public int change(int amount, int[] coins) {int[] dp = new int[amount+1];dp[0] = 1;for(int i = 0; i < coins.length; i++) {for(int j = coins[i]; j <= amount; j++) {dp[j] += dp[j - coins[i]];}}return dp[amount];}
}

三、377. 组合总和 Ⅳ

题目链接:https://leetcode.cn/problems/combination-sum-iv/description/
思路:和上一题类似,也是物品无限使用,是完全背包,但是不同的是求的是排列数。物品和背包都正序,背包在外,物品在内。

class Solution {public int combinationSum4(int[] nums, int target) {int[] dp = new int[target+1];dp[0] = 1;for(int i = 1; i <= target; i++) {for(int j = 0; j < nums.length; j++) {if(nums[j] > i) continue;dp[i] += dp[i - nums[j]];}}return dp[target];}
}

四、57. 爬楼梯(第八期模拟笔试)

题目链接:https://kamacoder.com/problempage.php?pid=1067
思路:本题是总楼梯数是背包总数,每次可以爬的楼梯数(1 <= m < n),求有多少种爬楼的方法。所以很明显是完全背包求排列数,爬楼梯的方法1,2和2,1明细是两种方法。所以直接套公式,完全背包求排列数,背包在外,物品在内。背包和物品都正序。
同时推荐一下卡码网,可以练习ACM模式。

import java.lang.*;
import java.util.*;class Main{public static void main(String[] args) {Scanner scan = new Scanner(System.in);int n = scan.nextInt(), m = scan.nextInt();int[] dp = new int[n+1];dp[0] = 1;for(int i = 1; i <= n; i++) {for(int j = 1; j <= m; j++) {if(i >= j) {dp[i] += dp[i-j];}}}System.out.println(dp[n]);} 
}

五、322. 零钱兑换

题目链接:https://leetcode.cn/problems/coin-change/description/
思路:本题是物品数量无限,完全背包。对于完全背包求组合数,物品在外,背包在内,求排列数,背包在外,物品在内。
其他的比如求能装的最大最小个数,物品和背包没有顺序要求,所以在内在外都行,其他的没有了。

class Solution {public int coinChange(int[] coins, int amount) {int[] dp = new int[amount+1];Arrays.fill(dp, Integer.MAX_VALUE);dp[0] = 0;for(int i = 0; i < coins.length; i++) {for(int j = coins[i]; j <= amount; j++) {if(dp[j-coins[i]] == Integer.MAX_VALUE) continue;dp[j] = Math.min(dp[j], dp[j-coins[i]]+1);}}return dp[amount] == Integer.MAX_VALUE ? -1 : dp[amount];}
}

这篇关于力扣爆刷第128天之动态规划五连刷(一个零、零钱兑换、组合)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/940031

相关文章

Java调用C++动态库超详细步骤讲解(附源码)

《Java调用C++动态库超详细步骤讲解(附源码)》C语言因其高效和接近硬件的特性,时常会被用在性能要求较高或者需要直接操作硬件的场合,:本文主要介绍Java调用C++动态库的相关资料,文中通过代... 目录一、直接调用C++库第一步:动态库生成(vs2017+qt5.12.10)第二步:Java调用C++

C#如何动态创建Label,及动态label事件

《C#如何动态创建Label,及动态label事件》:本文主要介绍C#如何动态创建Label,及动态label事件,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C#如何动态创建Label,及动态label事件第一点:switch中的生成我们的label事件接着,

SpringCloud动态配置注解@RefreshScope与@Component的深度解析

《SpringCloud动态配置注解@RefreshScope与@Component的深度解析》在现代微服务架构中,动态配置管理是一个关键需求,本文将为大家介绍SpringCloud中相关的注解@Re... 目录引言1. @RefreshScope 的作用与原理1.1 什么是 @RefreshScope1.

MyBatis 动态 SQL 优化之标签的实战与技巧(常见用法)

《MyBatis动态SQL优化之标签的实战与技巧(常见用法)》本文通过详细的示例和实际应用场景,介绍了如何有效利用这些标签来优化MyBatis配置,提升开发效率,确保SQL的高效执行和安全性,感... 目录动态SQL详解一、动态SQL的核心概念1.1 什么是动态SQL?1.2 动态SQL的优点1.3 动态S

mybatis-plus 实现查询表名动态修改的示例代码

《mybatis-plus实现查询表名动态修改的示例代码》通过MyBatis-Plus实现表名的动态替换,根据配置或入参选择不同的表,本文主要介绍了mybatis-plus实现查询表名动态修改的示... 目录实现数据库初始化依赖包配置读取类设置 myBATis-plus 插件测试通过 mybatis-plu

基于Canvas的Html5多时区动态时钟实战代码

《基于Canvas的Html5多时区动态时钟实战代码》:本文主要介绍了如何使用Canvas在HTML5上实现一个多时区动态时钟的web展示,通过Canvas的API,可以绘制出6个不同城市的时钟,并且这些时钟可以动态转动,每个时钟上都会标注出对应的24小时制时间,详细内容请阅读本文,希望能对你有所帮助...

Vue中动态权限到按钮的完整实现方案详解

《Vue中动态权限到按钮的完整实现方案详解》这篇文章主要为大家详细介绍了Vue如何在现有方案的基础上加入对路由的增、删、改、查权限控制,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、数据库设计扩展1.1 修改路由表(routes)1.2 修改角色与路由权限表(role_routes)二、后端接口设计

前端 CSS 动态设置样式::class、:style 等技巧(推荐)

《前端CSS动态设置样式::class、:style等技巧(推荐)》:本文主要介绍了Vue.js中动态绑定类名和内联样式的两种方法:对象语法和数组语法,通过对象语法,可以根据条件动态切换类名或样式;通过数组语法,可以同时绑定多个类名或样式,此外,还可以结合计算属性来生成复杂的类名或样式对象,详细内容请阅读本文,希望能对你有所帮助...

Nginx实现动态封禁IP的步骤指南

《Nginx实现动态封禁IP的步骤指南》在日常的生产环境中,网站可能会遭遇恶意请求、DDoS攻击或其他有害的访问行为,为了应对这些情况,动态封禁IP是一项十分重要的安全策略,本篇博客将介绍如何通过NG... 目录1、简述2、实现方式3、使用 fail2ban 动态封禁3.1 安装 fail2ban3.2 配

Vue3中的动态组件详解

《Vue3中的动态组件详解》本文介绍了Vue3中的动态组件,通过`component:is=动态组件名或组件对象/component`来实现根据条件动态渲染不同的组件,此外,还提到了使用`markRa... 目录vue3动态组件动态组件的基本使用第一种写法第二种写法性能优化解决方法总结Vue3动态组件动态