首页 > 其他分享 >20天 hot 100 速通计划-day17

20天 hot 100 速通计划-day17

时间:2023-08-25 22:11:10浏览次数:47  
标签:背包 偷窃 速通 nums int 示例 day17 20 dp

动态规划

70. 爬楼梯

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以爬 12 个台阶。你有多少种不同的方法可以爬到楼顶呢?

示例 1:

输入:n = 2
输出:2
解释:有两种方法可以爬到楼顶。
1. 1 阶 + 1 阶
2. 2 阶

示例 2:

输入:n = 3
输出:3
解释:有三种方法可以爬到楼顶。
1. 1 阶 + 1 阶 + 1 阶
2. 1 阶 + 2 阶
3. 2 阶 + 1 阶

提示:

  • 1 <= n <= 45

动态规划,结构固定

动规五部曲

  1. 定义:明确数组下标含义以及数组元素含义
  2. 定式:明确递归公式
  3. 定初值:确定递归共识初始值
  4. 定序:确定遍历顺序
  5. 定中值:举例推导数组(Debug 用)
class Solution {
public:
    int climbStairs(int n) {
        // 一定要写,虽然没有递归,但是要提前返回,否则 for 循环不会执行,还可能出现下标越界
        if(n < 2) return n;
        // 1. 定义:明确数组下标含义以及数组元素含义
        vector<int> dp(n+1); // dp[i]表示爬到第i层的方法数

        // 2. 定式:明确递归公式
        // 爬到第i层的方法数等于爬到第i-1层的方法数加上爬到第i-2层的方法数
        // 即 dp[i] = dp[i-1] + dp[i-2]

        // 3. 定初值:确定递归共识初始值
        dp[1] = 1; // 爬到第1层只有1种方法
        dp[2] = 2; // 爬到第2层有2种方法

        // 4. 定序:确定遍历顺序
        // 由于要计算的是dp[n],所以需要从小到大遍历
        for(int i = 3; i <= n; i++){
            dp[i] = dp[i-1] + dp[i-2];
        }
        return dp[n];
    }
};

118. 杨辉三角

给定一个非负整数 numRows生成「杨辉三角」的前 numRows 行。

在「杨辉三角」中,每个数是它左上方和右上方的数的和。

img

示例 1:

输入: numRows = 5
输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]]

示例 2:

输入: numRows = 1
输出: [[1]]

提示:

  • 1 <= numRows <= 30
class Solution {
public:
    vector<vector<int>> generate(int numRows) {
        // 定义:triangle是一个二维数组,表示杨辉三角形
        // 数组的行数为numRows
        vector<vector<int>> triangle(numRows);

        for(int i = 0; i < numRows; i++) {
            // 定义:杨辉三角形中第i行的元素个数为i+1
            triangle[i].resize(i + 1);
            // 定初值:杨辉三角形中每一行的第一个元素均为1
            triangle[i][0] = 1;
            // 定初值:杨辉三角形中每一行的最后一个元素均为1
            triangle[i][i] = 1;

            for(int j = 1; j < i; j++) {
                // 定式:杨辉三角形中除了第一个和最后一个元素外,
                // 其余元素等于上一行中对应位置元素和前一个位置元素之和
                triangle[i][j] = triangle[i-1][j-1] + triangle[i-1][j];
            }
        }

        return triangle;
    }
};

198. 打家劫舍

你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警

给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。

示例 1:

输入:[1,2,3,1]
输出:4
解释:偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。
     偷窃到的最高金额 = 1 + 3 = 4 。

示例 2:

输入:[2,7,9,3,1]
输出:12
解释:偷窃 1 号房屋 (金额 = 2), 偷窃 3 号房屋 (金额 = 9),接着偷窃 5 号房屋 (金额 = 1)。
     偷窃到的最高金额 = 2 + 9 + 1 = 12 。

提示:

  • 1 <= nums.length <= 100
  • 0 <= nums[i] <= 400
  // 1. 定义:dp[i] 表示偷窃前 i 间房屋能够获取的最大金额
  // 2. 定式:dp[i] = max(dp[i-1], dp[i-2]+nums[i])
  // 当前房屋 i 可以选择偷窃或者不偷窃
  // 如果偷窃房屋 i,则最大金额为 dp[i-2]+nums[i]
  // 如果不偷窃房屋 i,则最大金额为 dp[i-1]
  // 3. 定初值:dp[0] = nums[0], dp[1] = max(nums[0], nums[1])
  // 只有一间房屋时只能偷窃该房屋,两间房屋时偷窃金额为较大的一间
  // 4. 定序:从小到大遍历
class Solution {
public:
    int rob(vector<int>& nums) {
        int n = nums.size();
        if (n == 0) {
            return 0;
        } else if (n == 1) {
            return nums[0];
        } else if (n == 2) {
            return max(nums[0], nums[1]);
        }
        vector<int> dp(n, 0);
        dp[0] = nums[0];
        dp[1] = max(nums[0], nums[1]);
        for (int i = 2; i < n; i++) {
            dp[i] = max(dp[i-2] + nums[i], dp[i-1]);
        }
        return dp[n-1];
    }
};

279. 完全平方数

给你一个整数 n ,返回 和为 n 的完全平方数的最少数量

完全平方数 是一个整数,其值等于另一个整数的平方;换句话说,其值等于一个整数自乘的积。例如,14916 都是完全平方数,而 311 不是。

示例 1:

输入:n = 12
输出:3 
解释:12 = 4 + 4 + 4

示例 2:

输入:n = 13
输出:2
解释:13 = 4 + 9

提示:

  • 1 <= n <= 104

特殊动态规划:01 背包

相较于一般动态规划,模板性更强

  1. 判断问题为 01 背包问题:背包容量有限,每个物品只能选择取或不取,目标是在限定背包容量的情况下,选择物品使得总价值最大化。
  2. 识别物品和背包
  3. 明确嵌套 for 循环顺序
  4. 套用 01 背包模板
class Solution {
// 数作物品,和作背包
// 求最少数量 → 非组合非排列 → 复用 01 背包 → 外物品,内背包
public:
    int numSquares(int n) {
        // dp[容量]
        // min 非零下标取 INT_MAX,零下标取 0
        vector<int> dp(n + 1, INT_MAX);
        dp[0] = 0;
        for(int i = 1; i * i <= n; i++){ // 外物品
            for(int j  = i * i; j <= n; j++){
                dp[j] = min(dp[j], dp[j - i * i] + 1);
            }
        }
        return dp[n];
    }
};

322. 零钱兑换

给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。

计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1

你可以认为每种硬币的数量是无限的。

示例 1:

输入:coins = [1, 2, 5], amount = 11
输出:3 
解释:11 = 5 + 5 + 1

示例 2:

输入:coins = [2], amount = 3
输出:-1

示例 3:

输入:coins = [1], amount = 0
输出:0

提示:

  • 1 <= coins.length <= 12
  • 1 <= coins[i] <= 231 - 1
  • 0 <= amount <= 104
class Solution {
public:
    // 数作物品,和作背包
    // 硬币任取 → 完全背包 → 内正序
    // 最小个数 → 非组合非排列 → 复用 01 背包嵌套顺序:外物品,内背包
    int coinChange(vector<int>& coins, int amount) {
    // dp[容量]
    // 取最值,min 非零下标取 INT_MAX,零下标取 0
    vector<int> dp(amount + 1, INT_MAX); // 能取 amount
    dp[0] = 0; //凑 0 金额,不用硬币,故为 0
    for(int i = 0; i < coins.size(); i++){//外物品,内背包
        for(int j = coins[i]; j <= amount; j++){
            if(dp[j-coins[i]] != INT_MAX){
                dp[j] = min(dp[j], dp[j - coins[i]] + 1);
            }
        }
    }
    if(dp[amount] == INT_MAX) return -1;
    return dp[amount];
    }
};

标签:背包,偷窃,速通,nums,int,示例,day17,20,dp
From: https://www.cnblogs.com/ba11ooner/p/17658056.html

相关文章

  • 高频SQL 50题(基础版): 学生们参加各科测试的次数 | 2023-08-25
    问题学生表:Students+---------------+---------+|ColumnName|Type|+---------------+---------+|student_id|int||student_name|varchar|+---------------+---------+在SQL中,主键为student_id(学生ID)。该表内的每一行都记录有学校一名学生......
  • GDKOI 2023 游记
    前言这个东西还是lsz提醒我的()cj开了2G,,,day-114514班主任叫我去找cj,cj说她发现GDKOI的时候报名时间过了()最后好像还是有了名额。day-2被政治老师抽背政治,不会,当场寄掉,喜提罚抄提纲+重背。day-1无聊,躺在床上睡不着day0去广州了,没遇到js那群人。在六中里面迷......
  • [20230825]dc命令复杂学习.txt
    [20230825]dc命令复杂学习.txt--//前几天学习dc使用,我当时最后举了一个累加的例子,里面--//-e后面那一串什么意思,即使看了mandc文档,我当时也没看懂表示什么意思.尝试看了man文档,简单解析如下:--//我从文档里面取出相关说明:[characters]Makesastringcontainingcharacters......
  • 2023中考游寄
    算了既然有人想看那我就写写吧。day-1返校答疑。然后老子他妈内宿要一直到28号才能回家。然后就是我被五个人杰哥了。day0一整天都在图书馆自习,很无聊。偷偷抽了本《C++编程指南与实战》。不如蓝书。中午托同学家长送吃的,肠粉,14,好吃。晚上的不好次。晚上整个宿舍剩两人......
  • AT_donuts_2015_3 题解
    根据题意,发现我们要维护一个身高递减的序列。因此,我们可以直接使用单调栈维护第\(i\)个人能看到的人数即可。答案就是当前栈内的元素数量。注意应先输出答案再将当前高度入栈。#include<cstdio>intn;inth[100010];intst[100010];inttop;intmain(){ scanf("%d",&......
  • ABC020C题解
    本题二分+搜索。我们可以先二分出\(x\)可能的值,再用搜索检验这个答案是否满足要求。若满足,左端点右移,否则右端点左移。至于搜索可以用记搜加速。注意输出要换行,否则会WA。#include<cstdio>#include<cstring>intn,m,t;charmap[20][20];intsx,sy;intex,ey;longl......
  • stjzoi-2022
    在jzsc的时候豪哥就已经跟我们说好了7.13要来参加上一次在上半学期的复赛因为疫情,拖了一个学期,终于有了下文了在古老的初赛中以80/100的成绩进了复赛从jzsc回来后,跟父母说好了,参加比赛后要AFO直到作业写完但是由于我的期末考考的十分【数据删除】所以作业一大堆又因为初二的O......
  • 2023年8月25日
    1.通过构造函数创建对象的案例<script>//创建对象的方法有三种consto1={name:"张三"};consto2=newObject({name:"李四"});functionPeople(name){this.name=name;}consto3=newPeople("王五");......
  • 2023.8.25 LGJ Round
    AAlice和Bob玩一个游戏,Alice先手。有一个长度为偶数的字符串,每次取出该字符串最前或最后的字符并删掉,并把该字符加入自己的字符串末尾。双方都采取最优策略,问谁的字符串字典序更小,或相同。区间dp.\(dp_{i,j}\)表示\([i,j]\)这个区间先手必胜/必败/平局。初始\(dp_{......
  • ubuntu 20版本安装vnc连接灰屏问题
    修改vim  ~/.vnc/xstartup#!/bin/shautocutsel-forkxrdb$HOME/.Xresourcesxsetroot-solidgreyexportXKL_XMODMAP_DISABLE=1exportXDG_CURRENT_DESKTOP="GNOME-Flashback:Unity"exportXDG_MENU_PREFIX="gnome-flashback-"unsetDBUS_SESSION......