代码随想录算法训练营day36|动态规划part04

ops/2024/10/11 11:21:37/

第一题:1049. Last Stone Weight II

一维数组版本

class Solution {public int lastStoneWeightII(int[] stones) {int sum = 0;for (int i : stones) {sum += i;}int target = sum >> 1;//初始化dp数组int[] dp = new int[target + 1];for (int i = 0; i < stones.length; i++) {//采用倒序for (int j = target; j >= stones[i]; j--) {//两种情况,要么放,要么不放dp[j] = Math.max(dp[j], dp[j - stones[i]] + stones[i]);}}return sum - 2 * dp[target];}
}

二维数组版本(便于理解)

class Solution {public int lastStoneWeightII(int[] stones) {int sum = 0;for (int s : stones) {sum += s;}int target = sum / 2;//初始化,dp[i][j]为可以放0-i物品,背包容量为j的情况下背包中的最大价值int[][] dp = new int[stones.length][target + 1];//dp[i][0]默认初始化为0//dp[0][j]取决于stones[0]for (int j = stones[0]; j <= target; j++) {dp[0][j] = stones[0];}for (int i = 1; i < stones.length; i++) {for (int j = 1; j <= target; j++) {//注意是等于if (j >= stones[i]) {//不放:dp[i - 1][j] 放:dp[i - 1][j - stones[i]] + stones[i]dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - stones[i]] + stones[i]);} else {dp[i][j] = dp[i - 1][j];}}}System.out.println(dp[stones.length - 1][target]);return (sum - dp[stones.length - 1][target]) - dp[stones.length - 1][target];}
}

第二题:494. Target Sum 

class Solution {public int findTargetSumWays(int[] nums, int target) {int sum = 0;for (int i = 0; i < nums.length; i++) sum += nums[i];//如果target的绝对值大于sum,那么是没有方案的if (Math.abs(target) > sum) return 0;//如果(target+sum)除以2的余数不为0,也是没有方案的if ((target + sum) % 2 == 1) return 0;int bagSize = (target + sum) / 2;int[] dp = new int[bagSize + 1];dp[0] = 1;for (int i = 0; i < nums.length; i++) {for (int j = bagSize; j >= nums[i]; j--) {dp[j] += dp[j - nums[i]];}}return dp[bagSize];}
}

易于理解的二维数组版本:

class Solution {public int findTargetSumWays(int[] nums, int target) {// 01背包应用之“有多少种不同的填满背包最大容量的方法“// 易于理解的二维数组解法及详细注释int sum = 0;for(int i = 0; i < nums.length; i++) {sum += nums[i];}// 注意nums[i] >= 0的题目条件,意味着sum也是所有nums[i]的绝对值之和// 这里保证了sum + target一定是大于等于零的,也就是left大于等于零(毕竟我们定义left大于right)if(sum < Math.abs(target)){return 0;}// 利用二元一次方程组将left用target和sum表示出来(替换掉right组合),详见代码随想录对此题的分析// 如果所求的left数组和为小数,则作为整数数组的nums里的任何元素自然是没有办法凑出这个小数的if((sum + target) % 2 != 0) {return 0;}int left = (sum + target) / 2;// dp[i][j]:遍历到数组第i个数时, left为j时的能装满背包的方法总数int[][] dp = new int[nums.length][left + 1];// 初始化最上行(dp[0][j]),当nums[0] == j时(注意nums[0]和j都一定是大于等于零的,因此不需要判断等于-j时的情况),有唯一一种取法可取到j,dp[0][j]此时等于1// 其他情况dp[0][j] = 0// java整数数组默认初始值为0if (nums[0] <= left) {dp[0][nums[0]] = 1;}// 初始化最左列(dp[i][0])// 当从nums数组的索引0到i的部分有n个0时(n > 0),每个0可以取+/-,因此有2的n次方中可以取到j = 0的方案// n = 0说明当前遍历到的数组部分没有0全为正数,因此只有一种方案可以取到j = 0(就是所有数都不取)int numZeros = 0;for(int i = 0; i < nums.length; i++) {if(nums[i] == 0) {numZeros++;}dp[i][0] = (int) Math.pow(2, numZeros);}// 递推公式分析:// 当nums[i] > j时,这时候nums[i]一定不能取,所以是dp[i - 1][j]种方案数// nums[i] <= j时,num[i]可取可不取,因此方案数是dp[i - 1][j] + dp[i - 1][j - nums[i]]// 由递推公式可知,先遍历i或j都可for(int i = 1; i < nums.length; i++) {for(int j = 1; j <= left; j++) {if(nums[i] > j) {dp[i][j] = dp[i - 1][j];} else {dp[i][j] = dp[i - 1][j] + dp[i - 1][j - nums[i]];}}}// 打印dp数组// for(int i = 0; i < nums.length; i++) {//     for(int j = 0; j <= left; j++) {//         System.out.print(dp[i][j] + " ");//     }//     System.out.println("");// }return dp[nums.length - 1][left];}
}

第三题:474. Ones and Zeroes

class Solution {public int findMaxForm(String[] strs, int m, int n) {//dp[i][j]表示i个0和j个1时的最大子集int[][] dp = new int[m + 1][n + 1];int oneNum, zeroNum;for (String str : strs) {oneNum = 0;zeroNum = 0;for (char ch : str.toCharArray()) {if (ch == '0') {zeroNum++;} else {oneNum++;}}//倒序遍历for (int i = m; i >= zeroNum; i--) {for (int j = n; j >= oneNum; j--) {dp[i][j] = Math.max(dp[i][j], dp[i - zeroNum][j - oneNum] + 1);}}}return dp[m][n];}
}

 


http://www.ppmy.cn/ops/90164.html

相关文章

【深度学习】【语音】TTS,StyleTTS 2,论文

StyleTTS 2 是一款创新的文本转语音(TTS)模型,通过使用样式扩散和大规模语音语言模型(SLM)的对抗训练,实现了接近人类水平的TTS合成。以下是StyleTTS 2在技术上的几个关键点和其在性能上的突出表现: 技术重点 样式扩散(Style Diffusion): StyleTTS 2 将语音样式建模…

中建海龙科技模块化集成建筑(MiC建筑):高效省时,建筑新选择

在当今快速发展的建筑行业中&#xff0c;时间成本往往成为制约项目进度的关键因素。中建海龙科技凭借其原创的模块化集成建筑&#xff08;MiC建筑&#xff09;技术&#xff0c;不仅实现了建筑的高质量、高效率&#xff0c;更在节省时间方面展现出了显著优势。 模块化集成建筑&…

WriterSide 文档、接口自动编译并部署到GitPage

WriterSide 自动编译并部署到GitPage 1. GitHub 创建空仓库2. 配置GitHub 仓库的编译部署方式3. WriteSide 创建项目4. 创建自动、编译部署配置文件5. 自动编译、部署1. GitHub 创建空仓库 在 GitHub 创建一个空的仓库 仓库创建成功后, 记录仓库的远程地址 仓库地址需要修改…

html+css前端作业和平精英2个页面(无js)

htmlcss前端作业和平精英2个页面&#xff08;无js&#xff09;有视频播放器等功能效果 网页作品代码简单&#xff0c;可使用任意HTML编辑软件&#xff08;如&#xff1a;Dreamweaver、HBuilder、Vscode 、Sublime 、Webstorm、Text 、Notepad 等任意html编辑软件进行运行及修改…

架构师软考-每日两道单选题6

第11题 单选题 在软件系统工具中&#xff0c;版本控制工具属于&#xff08; &#xff09;&#xff0c;软件评价工具属于&#xff08;/&#xff09;。 A 软件开发工具 B 软件维护工具 C 编码与排错工具 D 软件管理和软件支持工具 解析 在软件系统工具中&#xff0c;版本控制工…

【C++入门(下)】—— 我与C++的不解之缘(二)

前言 接上篇&#xff0c;继续来学习C&#xff0c;本篇内容大概有 引用&#xff0c;inline 和 nullptr。 六、引用&#xff1a; 6.1、引用的定义 引用不是新定义一个变量&#xff0c;而是给已存在的变量取了一个别名&#xff0c;编译器不会为引用变量开辟内存空间&#xff0c;它…

数模——灰色关联分析算法

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 文章目录 前言 一、基本概念了解 1.什么是灰色系统&#xff1f; 2.什么是关联分析&#xff1f; 二、模型原理 三、建模过程 1.找母序列&#xff08;参考序列&am…

简单的docker学习 第3章 docker镜像

第3章 Docker 镜像 3.1镜像基础 3.1.1 镜像简介 ​ 镜像是一种轻量级、可执行的独立软件包&#xff0c;也可以说是一个精简的操作系统。镜像中包含应用软件及应用软件的运行环境。具体来说镜像包含运行某个软件所需的所有内容&#xff0c;包括代码、库、环境变量和配置文件等…