代码随想录算法训练营|动态规划三十八天~四十三天

 动态规划五部曲:

1、确定dp数组以及下标的含义

2、确定递推公式

3、dp数组如何初始化

4、确定遍历顺序

5、举例推导dp数组

三十八天

斐波那契数

509. 斐波那契数 - 力扣(LeetCode)

public class Solution {
    public int MonotoneIncreasingDigits(int n) {
        string s = n.ToString();
        
        int size = s.Length;
        for(int i=s.Length-1;i>0;i--){
            if(s[i-1] > s[i]){
                size=i;
                s = s.Substring(0,i-1)+(char)(s[i-1]-1)+s.Substring(i);
            }
        }
        for(int i=size;i<s.Length;i++){
            s = s.Substring(0,i)+'9'+s.Substring(i+1);
        }
        return int.Parse(s);
    }
}

爬楼梯

70. 爬楼梯 - 力扣(LeetCode)

public class Solution {
    public int ClimbStairs(int n) {
        if(n==1){return n;}
        int[] result = new int[n+1];
        result[1] = 1;
        result[2] = 2;
        for(int i=3;i<=n;i++){
            result[i] = result[i-1]+result[i-2];
        }

        return result[n];
    }
}

使用最少花费爬楼梯

746. 使用最小花费爬楼梯 - 力扣(LeetCode)

public class Solution {
    public int MinCostClimbingStairs(int[] cost) {
        if(cost.Length == 1){return 0;}

        int[] result = new int[cost.Length+1];
        result[0] = 0;
        result[1] = 0;
        for(int i=2;i<=cost.Length;i++){
            result[i] = Math.Min(result[i-1]+cost[i-1],result[i-2]+cost[i-2]);
        }
        return result[cost.Length];
    }
}

三十九天

不同路径

62. 不同路径 - 力扣(LeetCode)

按照五部曲,dp数组含义是从起点到[i,j]的路径总共有result[i,j]条路径;递归就是在点[0,0]到[1,1]有两条路,即[0,1]和[1,0],所以result[i,j]=result[i-1,j]+result[i,j-1];初始化就把纵横赋值为1,因为只有一个方法走,

public class Solution {
    public int UniquePaths(int m, int n) {
        int[,] result = new int[n,m];
        
        for(int i=0;i<n;i++){result[i,0] = 1;}
        for(int j=0;j<m;j++){result[0,j] = 1;}

        for(int i=1;i<n;i++){
            for(int j=1;j<m;j++){
                result[i,j] = result[i-1,j] + result[i,j-1];
            }
        }

        return result[n-1,m-1];
    }
}

不同路径||

63. 不同路径 II - 力扣(LeetCode)

和上一题比就多了个障碍,只要把障碍的位置记录就行了。

public class Solution {
    public int UniquePathsWithObstacles(int[][] obstacleGrid) {
        int n = obstacleGrid.Length;
        int m = obstacleGrid[0].Length;
        int[,] result = new int[n,m];

        if(obstacleGrid[n-1][m-1] == 1 || obstacleGrid[0][0] == 1){return 0;}

        for(int i=0;i<n && obstacleGrid[i][0] == 0;i++){
            result[i,0] = 1;
        }
        for(int i=0;i<m && obstacleGrid[0][i] == 0;i++){
            result[0,i] = 1;
        }

        for(int i=1;i<n;i++){
            for(int j=1;j<m;j++){
                if(obstacleGrid[i][j] != 1){
                    result[i,j] = result[i-1,j]+result[i,j-1];
                }
            }
        }

        return result[n-1,m-1];
    }
}

四十天

整数拆分

343. 整数拆分 - 力扣(LeetCode)

要点:这题递推比较难,有两个拆分方向,一个是j*(i-j),一个是j*result[i-j]。例如输入5,拆分1,4,然后4可以继续拆分成1,3,然后就取1*4和1*1*3的最大值,再赋值到result[i]

public class Solution {
    public int IntegerBreak(int n) {
        int[] result = new int[n+1];
        result[2] = 1;

        for(int i=3;i<=n;i++){
            for(int j=1;j<i-1;j++){
                result[i] = Math.Max(result[i],Math.Max(j*(i-j),j*result[i-j]));
            }
        }

        return result[n];
    }
}

不同的二叉搜索树

96. 不同的二叉搜索树 - 力扣(LeetCode)

要点:首先就是二叉树的左边比头结点小,右边比头结点大,其次,根据例题输入n=3,图,以及二叉树的特性,能推断出result[3] = result[2]*result[0] + result[1]*result[1] + result[0]*result[2],就是左子树元素节点数量*右子树元素节点数量。

关于result[0]=1:

从定义上来讲,空节点也是一棵二叉树,也是一棵二叉搜索树,这是可以说得通的。

从递归公式上来讲,dp[以j为头结点左子树节点数量] * dp[以j为头结点右子树节点数量] 中以j为头结点左子树节点数量为0,也需要dp[以j为头结点左子树节点数量] = 1, 否则乘法的结果就都变成0了。

public class Solution {
    public int NumTrees(int n) {
        int[] result = new int[n+1];
        result[0] = 1;

        for(int i=1;i<=n;i++){
            for(int j=1;j<=i;j++){
                result[i] += result[j-1]*result[i-j];
            }
        } 

        return  result[n];
    }
}

四十一天

背包问题

二维dp数组01背包:(详细看代码随想录 (programmercarl.com))

1、dp[i][j] 表示从下标为[0-i]的物品里任意取,放进容量为j的背包,价值总和最大是多少。

2、递推公式:dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i])

不放物品i:dp[i - 1][j](由dp[i - 1][j]推出,即背包容量为j,里面不放物品i的最大价值,此时dp[i][j]就是dp[i - 1][j]。(其实就是当物品i的重量大于背包j的重量时,物品i无法放进背包中,所以背包内的价值依然和前面相同);

放物品:dp[i - 1][j - weight[i]] + value[i](由dp[i - 1][j - weight[i]]推出,dp[i - 1][j - weight[i]] 为背包容量为j - weight[i]的时候不放物品i的最大价值,那么dp[i - 1][j - weight[i]] + value[i] (物品i的价值),就是背包放物品i得到的最大价值)。

3、初始化

从dp[0][0]开始,纵向初始化为0,横向i>0,都初始化为物品0能放进背包时的价值,放不进也初始化为0;其他的也都可以初始化为0。

4、遍历顺序:

先遍历物品或者背包都可以。

先遍历物品

// weight数组的大小 就是物品个数
for(int i = 1; i < weight.size(); i++) { // 遍历物品
    for(int j = 0; j <= bagweight; j++) { // 遍历背包容量
        if (j < weight[i]) dp[i][j] = dp[i - 1][j];
        else dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);

    }
}

一维数组(滚动数组,就是每次循环都覆盖在原来的数组中,二维数组是i*j的数组,一维数组只需要j)

1、dp[j]表示容量为j的背包,所背的物品价值可以最大为dp[j]。

2、递推公式:dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);

3、初始化:全部初始为0.

4、遍历顺序

for(int i = 0; i < weight.size(); i++) { // 遍历物品
    for(int j = bagWeight; j >= weight[i]; j--) { // 遍历背包容量
        dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);

    }
}

 分割等和字集

416. 分割等和子集 - 力扣(LeetCode)

要点:这题是前面背包问题的应用,然后一维数组的递推公式在这里的平替是背包体积是target,重量和价值是nums。不过我还没完全懂,先挂在这后面慢慢想。

public class Solution {
    public bool CanPartition(int[] nums) {
        bool[] dp = new bool[10000];

        int sum = nums.Sum();
        if(sum % 2 == 1){return false;}
        int target = sum / 2;

        dp[0] =true;
        for(int i=0;i<nums.Length;i++){
            for(int j=target;j>=nums[i];j--){
                dp[j] = dp[j] || dp[j-nums[i]];
            }
        }
        return dp[target];
    }
}

四十二天

最后一块石头的重量||

1049. 最后一块石头的重量 II - 力扣(LeetCode)

和分割等和子集同样的思路

public class Solution {
    public int LastStoneWeightII(int[] stones) {
        int sum = stones.Sum();
        int target = sum/2;
        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];  
    }
}

目标和

494. 目标和 - 力扣(LeetCode)

public class Solution {
    public int FindTargetSumWays(int[] nums, int target) {
        int sum = nums.Sum();
        if(Math.Abs(target) > sum){return 0;}
        if((target+sum)%2 == 1){return 0;}
        int bagLength = (target+sum) / 2;
        int[] dp = new int[bagLength+1];
        dp[0] = 1;
        for(int i=0;i<nums.Length;i++){
            for(int j=bagLength;j>=nums[i];j--){
                dp[j] += dp[j-nums[i]];
            }
        }
        return dp[bagLength];
    }
}

一和零

474. 一和零 - 力扣(LeetCode)

public class Solution {
    public int FindMaxForm(string[] strs, int m, int n) {
        int[,] dp= new int[m+1,n+1];
        foreach(string s in strs){
            int zeroNum = 0;
            int oneNum = 0;
            foreach(char a in s){
                if(a == '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];
    }
}

目前,我对所有的01背包问题都不懂!

四十三天

完全背包:所有物品都能无限放入背包

零钱兑换||

518. 零钱兑换 II - 力扣(LeetCode)

看起来和那个目标和的题差不多,对物品的使用次数没限制。不过还是不太懂。

public 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];
    }
}

组合总和IV

377. 组合总和 Ⅳ - 力扣(LeetCode)

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于Java+SpringBoot+Vue3+TypeScript前后端分离商城后台管理系统设计与实现

博主介绍&#xff1a;✌全网粉丝5W&#xff0c;全栈开发工程师&#xff0c;从事多年软件开发&#xff0c;在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战&#xff0c;博主也曾写过优秀论文&#xff0c;查重率极低&#xff0c;在这方面有丰富的经验…

Technology Strategy Patterns 学习笔记6-Communicating the Strategy-Approach Patterns

1 30-Second Answer 1.1 类似麦肯锡电梯谈话 Map an outline of three bullet points in your head, and then give the executives the simple, declarative, definitive answerAdd your three reasons or characterizations with your three bullet points also as high-le…

详解数据仓库之拉链表(原理、设计以及在Hive中的实现)

最近发现一本好书&#xff0c;读完感觉讲的非常好&#xff0c;首先安利给大家&#xff0c;国内第一本系统讲解数据血缘的书&#xff01;点赞&#xff01;近几天也会安排朋友圈点赞赠书活动(ง•̀_•́)ง 0x00 前言 本文将会谈一谈在数据仓库中拉链表相关的内容&#xff0c;包…

文件基础IO

1.先回忆一下c语言的文件接口&#xff1a; fopen,fwrite: 对应的代码如下&#xff1a; 注意fopen和fwrite的用法&#xff1a; 代码结果&#xff1a; 对应的strlen不需要1吗&#xff0c;不需要\0对应的是c语言的存储方式&#xff0c;和操作系统无关。 可以看到已经在对应的文…

使用3D Touch,让你左右逢源,操作更自然

本文介绍了如何在苹果设备上使用3D Touch&#xff0c;以及哪些应用程序支持该工具。3D Touch在Apple Watch上也称为Force Touch&#xff0c;在iPhone XR上也称为Haptic Touch。 如何改变3D触摸的灵敏度 按照以下步骤调整3D Touch的灵敏度&#xff1a; 1、打开“设置”应用程…

HTML5+CSS3+Vue小实例:输入框打字放大特效

实例:输入框打字放大特效 技术栈:HTML+CSSS+JS 效果: 源码: 【HTML】 <!DOCTYPE html> <html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"><meta name="viewport" content=&…

使用Nodejs搭建简单的Web网页并实现公网访问

目录 前言 1. 安装Node.js环境 2. 创建Node.js应用 3. 安装Cpolar内网穿透实现公网访问Nodejs服务 3.1 注册cpolar账号 3.2 下载cpolar客户端 3.3 创建隧道映射本地端口 4. 固定公网远程地址 前言 Node.js是建立在谷歌Chrome的JavaScript引擎(V8引擎)的Web应用程序框架…

翻译环境(编译和链接)(简单讲解,理解图就行)

前言 这是我们学习代码的最重要的一个知识点之一&#xff0c;因为我们要去运行一个代码并不是简单的去直接出结果&#xff0c;而是经过了很多我们看不到的步骤&#xff0c;我们在这里以C语言为例子在Linux的环境下讲解&#xff0c;大家没有学过Linux的不用担心&#xff0c;最后…

Maya 2024 for Mac(3D建模软件)

Maya 2024是一款三维计算机图形软件&#xff0c;具有强大的建模、动画、渲染、特效等功能&#xff0c;广泛应用于影视、游戏、广告等行业。以下是Maya 2024软件的主要功能介绍&#xff1a; 建模&#xff1a;Maya 2024具有强大的建模工具&#xff0c;包括多边形建模、曲面建模、…

功能强大的制作电子杂志网站,小白也可轻松上手

现在&#xff0c;越来越多的人开始关注电子杂志的制作&#xff0c;因为它不仅时尚&#xff0c;而且方便快捷。如果你是一个新手&#xff0c;想要制作一本属于自己的电子杂志&#xff0c;那么今天这个网站一定不能错过。它不仅功能强大&#xff0c;而且操作简单&#xff0c;小白…

Windows系统安装Redis、配置环境变量

系列文章目录 第一章 Java线程池技术应用 第二章 CountDownLatch和Semaphone的应用 第三章 Spring Cloud 简介 第四章 Spring Cloud Netflix 之 Eureka 第五章 Spring Cloud Netflix 之 Ribbon 第六章 Spring Cloud 之 OpenFeign 第七章 Spring Cloud 之 GateWay 第八章 Sprin…

【C++基础 】类和对象(上)

C基础 类和对象&#xff08;上&#xff09; 1.面向过程和面向对象初步认识2.类的引入3.类的定义4.类的访问限定符及封装4.1 访问限定符4.2 封装 5.类的作用域6.类的实例化7.类对象模型7.1 如何计算类对象的大小7.2 类对象的存储方式猜测7.3 结构体内存对齐规则 8.this指针8.1 t…

非遗文化展示预约小程序的效果如何

漫漫历史长河&#xff0c;我国积累的各种非遗文化广而多&#xff0c;也有相应的机构整理展示和收录&#xff0c;区域限制下&#xff0c;传统非遗文化内容传播度并不高&#xff0c;实际线下查看了解的人也并不是很多&#xff0c;在实际展示方面也面临着一些难题&#xff1a; 线…

【Java面向对象编程(中)】- 探索封装的秘密

&#x1f308;个人主页: Aileen_0v0&#x1f525;系列专栏:Java学习系列专栏&#x1f4ab;个人格言:"没有罗马,那就自己创造罗马~" 目录 回顾 封装​编辑 为什么进行封装 ​​编辑​ 如何调用私有的变量 ​​编辑​ 1.get set方法(当形参和成员变量不同名时)​…

游戏平台采集数据

首先&#xff0c;你需要在你的项目中添加Kotlin的网络库&#xff0c;例如OkHttp。你可以在你的build.gradle文件中添加以下依赖&#xff1a; dependencies {implementation com.squareup.okhttp3:okhttp:4.9.0 }然后&#xff0c;你可以使用以下代码来创建一个基本的网络爬虫&a…

基于python+django的美食餐厅点餐订餐网站

运行环境 开发语言&#xff1a;Python python框架&#xff1a;django 软件版本&#xff1a;python3.7 数据库&#xff1a;mysql 5.7 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;PyCharm/vscode 前端框架:vue.js 项目介绍 本论文主要论述了如何使用python语言开发…

原码补码相关运算

求补码步骤 原补转换 -127为负数&#xff0c;其补码为原码01111111&#xff0c;取反10000000&#xff0c;加一&#xff0c;10000001。 例如&#xff1a; 【-1】原码 10000001 反码bai11111110 补码duzhi 11111111 【3】原码 00000011 反码 00000011 补码 00000011 【-127】…

在Ubuntu下安装Redis

文章目录 前言一、配置JAVA运行环境二、Ubuntu下安装Redis1.安装c语言编译环境2.下载解压Redis3.make编译4.启动Redis4.运行Redis 三、性能测试总结 前言 版本 jdk版本&#xff1a;jdk-17_linux-x64_bin 地址&#xff1a;https://www.oracle.com/cn/java/technologies/downloa…

Ubuntu 创建并发布 Django 项目

Ubuntu 创建并发布 Django 项目 升级操作系统和软件 sudo apt updatesudo apt -y dist-upgrade 安装 python3-pip sudo apt -y install python3-pip安装 django pip install -i https://pypi.tuna.tsinghua.edu.cn/simple djangosudo apt -y install python3-django创建 dj…

Django基础介绍及HTTP请求

文章目录 Django框架的介绍Django的安装 Django框架开发创建项目的指令Django项目的目录结构URL 介绍视图函数(view)Django 中的路由配置带有分组的路由和视图函数带有命名分组的路由和视图函数 HTTP协议的请求和响应HTTP 请求HTTP 响应GET方式传参POST传递参数form 表单的name…