当前位置: 首页 > news >正文

【leetcode100-081到090】【动态规划】一维五题合集1

【爬楼梯】

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

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

思路:

  • 【状态】

     dp[i];//爬i级台阶有几种方法
  • 【初始】

     dp[0] = 1;//爬0级1种(不爬)dp[1] = 1;//爬1级1种
  • 【递推】

     dp[i] = dp[i-2] + dp[i-1];//爬i级=先爬i-1级再爬1级+先爬i-2级再爬2级,没有其他可能了
  • 【结论】

     dp[n];//爬n级方法数
class Solution {
public:int climbStairs(int n) {vector<int> dp(n + 1);dp[0] = 1;dp[1] = 1;for (int i = 2; i <= n; i++) {dp[i] = dp[i - 1] + dp[i - 2];}return dp[n];}
};

【杨辉三角】

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

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

思路:

观察示例可以发现:

每一行的行号也是该行元素的最大下标;

每行的首尾元素是1;

其余元素是它左上和右上元素的和;

把以上规则翻译成代码语言即可。

class Solution {
public:vector<vector<int>> generate(int numRows) {vector<vector<int>> ans;vector<int> lastRow(1,1);ans.push_back(lastRow);if (numRows == 1)return ans;for (int i = 1; i < numRows; i++) {vector<int> curRow;//当前行最大下标就是icurRow.push_back(1);for (int j = 1; j < i; j++) {curRow.push_back(lastRow[j - 1] + lastRow[j]);}curRow.push_back(1);ans.push_back(curRow);lastRow.resize(i+1);lastRow = curRow;}return ans;}
};

【打家劫舍】

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

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

思路:

建立dp数组,dp[i]代表到房子i为止最高可以偷到的金额。

对当前房子,我们分别计算偷它和不偷它可以获得的最大金额,并记录两者中较大的那个:

偷它,那么i-1号房子不可以偷,总金额是,偷i-2及以前的房子+偷i;

不偷它,那么i-1房子可以偷,总金额就是偷i-1及以前的房子;

class Solution {
public:int rob(vector<int>& nums) {int n = nums.size();if (n == 1)return nums[0];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(nums[i] + dp[i - 2], dp[i - 1]);}return dp[n - 1];}
};

【完全平方数】

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

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

思路:

本题从如何减小问题规模入手。

首先,对拿到的数,我们已经知道任意一个比它小的数最少由几个完全平方数组成;

因此,我们可以先从当前数字中减掉一个完全平方数,然后通过dp直接拿到剩下的数的dp值,此时,这种切分方式得到的答案就是该dp值+1;

对当前数字,能从中减掉的完全平方数可能不止一个,因此,我们应该把能减的平方数全都试一遍,并把所有答案中最小的那个设为当前数字的dp值。

class Solution {
public:int numSquares(int n) {vector<int> dp(n + 1);dp[0] = 0;//填数组for (int k = 1; k <= n; k++) {int curMin = INT_MAX;//枚举平方根以下的数for (int i = 1; i * i <= k; i++) {curMin = min(curMin, dp[k - i * i]);}dp[k] = curMin + 1;}return dp[n];}
};

【零钱兑换】

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

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

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

思路:

和上一题本质上没有任何区别,只要把上一题枚举的“完全平方数”在这题改成“硬币面值”,就完事儿了。

class Solution {
public:int coinChange(vector<int>& coins, int amount) {int n = coins.size();sort(coins.begin(), coins.end());if (amount == 0)return 0;if (amount < coins[0])return -1;vector<int> dp(amount + 1);dp[0] = 0;//依次计算for (int i = 1; i <= amount; i++) {int curMin = INT_MAX;//记录当前金额能否凑成bool flag = false;// calculate dp[i]//枚举比总数小的所有硬币面值for (int j = 0; j < n && 0 <= i - coins[j]; j++) {//如果去掉当前面值以后能凑出来if (dp[i - coins[j]] != -1) {//记录最少数量curMin = min(curMin, dp[i - coins[j]] + 1);//记录可以凑出flag = true;}}dp[i] = flag ? curMin : -1;}return dp[amount];}
};

http://www.lryc.cn/news/291754.html

相关文章:

  • 数据结构-顺序表详解专题
  • 对商业知识和思维的一些小体会
  • 【笔记】计算文件夹的大小
  • 机器学习_常见算法比较模型效果(LR、KNN、SVM、NB、DT、RF、XGB、LGB、CAT)
  • 外包干了8个月,技术退步明显...
  • opencv#41 轮廓检测
  • Websocket基本用法
  • node.js与express.js创建项目以及连接数据库
  • 【Tomcat与网络8】从源码看Tomcat的层次结构
  • Java Agent Premain Agentmain
  • Python实现设计模式-策略模式
  • 详解SpringCloud微服务技术栈:深入ElasticSearch(4)——ES集群
  • AlmaLinux上安装Docker
  • 熟悉MATLAB 环境
  • 【数据库数据恢复】Oracle数据库ASM磁盘组数据恢复案例
  • STM32CubeMX教程31 USB_DEVICE - HID外设_模拟键盘或鼠标
  • 知道Wi-Fi名称和密码之后自动连接
  • 本地搭建Plex私人影音网站并结合内网穿透实现公网远程访问
  • 【算法】拦截导弹(线性DP)
  • 记 doris 加载压缩文件(lzo、snappy)pr
  • 【Leetcode】2670. 找出不同元素数目差数组
  • ༺༽༾ཊ—Unity之-01-工厂方法模式—ཏ༿༼༻
  • QT仪表盘小工具
  • 【2024】大三寒假再回首:缺乏自我意识是毒药,反思和回顾是解药
  • 计算机网络——网络层(3)
  • ROS2 学习笔记12:使用 colcon 构建软件包
  • 基于JAVA+SpringBoot+Vue的前后端分离的医院管理系统
  • npm淘宝镜像过期解决办法
  • Arduino 官网上下载和使用开发板
  • k8s学习-DaemonSet和Job