news 2026/10/29 11:10:44

小白做题日记(9)动态规划,洛谷老钱系列(纸币问题123)+ 力扣动态规划基础题

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
小白做题日记(9)动态规划,洛谷老钱系列(纸币问题123)+ 力扣动态规划基础题

感觉自己做题一直没什么规划,看到什么做什么,这几天就准备系统的练习一下动态规划了,这几天都在洛谷做动态规划吧。。。。

以下问题完全是纸币问题大家族来的。。。

1.https://www.luogu.com.cn/problem/P2842

状态转移方程:dp[i] = min{dp[i-aj]+1}

#include<iostream> using namespace std; int n,w; int dp[10005],a[1005]; int main(){ cin >> n >> w; fill(dp, dp + w + 1, w + 1); dp[0] = 0; for(int i = 0;i < n;i++){ cin >> a[i]; dp[a[i]] = 1; } for(int i = 1;i <= w;i++){ for(int j = 0;j < n;j++){ if(i < a[j]) continue; if(dp[i-a[j]]!= w+1) dp[i] = min(dp[i],dp[i-a[j]]+1); } } cout << dp[w]<<endl; return 0; }

2.https://www.luogu.com.cn/problem/P2840

“你是一个非常有钱的小朋友。”

这个题目求得是有多少种方案,那最后一张不一定是几,结果就是前一步所有情况,每种情况的方案数的和

所以状态转移方程就是:dp[i] = dp[i]+sum{dp[i-a[j]]}

#include<iostream> using namespace std; int n,w; int dp[10005],a[1005]; const int mod = 1e9+7; int main(){ cin >> n >> w; for(int i = 0;i < n;i++){ cin >> a[i]; } dp[0] = 1; for(int i = 1;i <= w;i++){ for(int j = 0;j < n;j++){ if(i >= a[j]){ dp[i] = (dp[i] +dp[i-a[j]])%mod; } } } cout <<dp[w] <<endl; return 0; }

3.https://www.luogu.com.cn/problem/P2834

bushi?

#include<iostream> using namespace std; int n,w; int dp[10005],a[1005]; const int mod = 1e9+7; int main(){ cin >> n >> w; for(int i = 0;i < n;i++){ cin >> a[i]; } dp[0] = 1; for(int i = 0;i < n;i++){ for(int j = a[i];j <= w;j++){ dp[j] = (dp[j] + dp[j-a[i]])%mod; } } cout <<dp[w] <<endl; return 0; }

我的大脑有点乱乱的了,怎么感觉又会又不会的。。。。

dp[j] = 不用当前纸币+至少用一张当前纸币

闪现力扣

今天的做题顺序是这样的

(这些题目都不太难,列列0123就能写出来状态转移方程,可以做做给自己点信心。。。。)主要是本小白做题总是会被打击啊喂,不过没关系我是打不死的小强,但是个人觉得对于刚开始学习动态规划理解这些内容是有帮助的,会感觉能想通很多细节,再慢慢的做后面的进阶题。如果直接给你一道动态规划的难题对我来说我会做的一知半解,很多细节就会觉得莫名其妙,跟着题解ac了之后后面出现类似的题还是不会做。。。。

1.70. 爬楼梯 - 力扣(LeetCode)

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

3.1137. 第 N 个泰波那契数 - 力扣(LeetCode)

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

5.198. 打家劫舍 - 力扣(LeetCode)

6.740. 删除并获得点数 - 力扣(LeetCode)

这道题可以转化为和5类似的题,就是这道题你选择n那么所有的n-1和n+1就都没有了,那么剩下的所有的n你就都可以选,现在就变成 数字->数字总和(每家谁的钱多),而且相邻的家不能打劫

class Solution { public: int deleteAndEarn(vector<int>& nums) { int maxnum = 0; for(int i : nums){ maxnum = max(i,maxnum); } vector<int> sum(maxnum+1,0); for(int i:nums){ sum[i] += i; } vector<int> dp(maxnum+1,0); dp[1] = sum[1]; for(int i = 2;i <= maxnum;i++){ dp[i] = max(dp[i-1],dp[i-2]+sum[i]); } return dp[maxnum]; } };

吃饱睡足回来了

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

这道题我开始用的是二维数组的写法,不怎么难想,然后我看到了题解中是优化为一维数组写的,遂学之。。

他是怎么将二维的f[i][j] = f[i-1][j]+f[i][j-1]变成一维的f[j] += f[j-1]的呢?

首先我们要先理解这个状态转移方程f[i]:表示的是在当前计算的这一行中,第j列有多少种走法

其实这俩式子就是一个意思

f[j] =f[j]+f[j-1]这个橙色的就是当前行的第j-1列那不就是原式的f[i][j-1],红色的是前一行的第j列,因为现在的这一行我们还没有更新,所以这里f[j]存的是第i-1行第j列的数据,也就是二维数组中的 f[i-1][j],OK过了!

class Solution { public: int uniquePaths(int m, int n) { vector<int> f(n,1); for(int i = 1;i < m;i++){ for(int j = 1;j < n;j++){ f[j] = f[j] + f[j-1]; } } return f[n-1]; } };

在第9题又碰到了降维优化的方法

滚动数组的核心思想:如果计算当前状态只需要前面少数几行的数据,就没必要把所有行都保存下来,可以重复利用数组空间

假设你需要计算 100 行数据,每一行都依赖上一行:

  • 计算第 1 行,需要第 0 行。

  • 计算第 2 行,需要第 1 行。

  • 计算第 3 行,需要第 2 行。

当你已经算出第 3 行时,还需要保留第 0 行的结果吗?

不需要了,因为接下来的计算只需要第 2 行和第 3 行附近的数据。

所以,我们可以准备两张草稿纸:

  • 一张保存上一行。

  • 一张计算当前行。

每算完一行,就交换两张草稿纸的角色。这样就不用准备 100 张草稿纸了。

这就是滚动数组思想。

8.64. 最小路径和 - 力扣(LeetCode)

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

如果当前点ij有障碍物,那么在当前这一行,第j列的走法一定是0,可以与第七题一起看,这道题目加了障碍物。

class Solution { public: int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) { int n = obstacleGrid.size(),m = obstacleGrid[0].size(); int f[105]; f[0] = (obstacleGrid[0][0] == 0?1:0); for(int i = 0;i < n;i++) { for(int j = 0;j < m;j++){ if(obstacleGrid[i][j] == 1){ f[j] = 0; continue; } if(j-1 >= 0 && obstacleGrid[i][j-1] == 0){ f[j] = f[j]+f[j-1]; } } } return f[m-1]; } };

10.120. 三角形最小路径和 - 力扣(LeetCode)

这道题也是二维转一维做的,这道题是自底向上来解决的,dp[j]表示在当前行第j列距离底部的最小距离,初始化是使用的数组的最后一行对dp进行初始化

class Solution { public: int minimumTotal(vector<vector<int>>& triangle) { int n = triangle.size(); vector<int> dp = triangle[n-1]; for(int i = n-2;i >= 0;i--){ for(int j = 0;j <= i;j++){ dp[j] = min(dp[j],dp[j+1])+triangle[i][j]; } } return dp[0]; } };
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/29 11:08:05

HDMI 无线传输:会议摄像头高清信号无线延伸方案实测(易视讯)

在会议室音视频项目调试中&#xff0c;经常会遇到 HDMI 高清信号远距离布线难题。很多 PTZ 会议摄像头输出 HDMI 信号&#xff0c;但主机、矩阵、采集端和摄像头距离较远&#xff0c;长距离 HDMI 线缆穿管、走线槽施工麻烦&#xff0c;已经装修完成的会场改造更是困难。HDMI 无…

作者头像 李华
网站建设 2026/10/29 11:07:52

Windows 电脑上安装 Docker Desktop

1、下载地址 下载地址:https://www.docker.com/products/docker-desktop/ 2、安装步骤 针对 x64 处理器的 Windows 电脑,选择下载 “Download for Windows - AMD64” 。 点击下载的 “Docker Desktop Installer.exe”,会按默认路径进行安装,默认路径是安装在C盘,没办法手…

作者头像 李华
网站建设 2026/10/29 11:07:07

AI时代,程序员如何从执行者转型?收藏这份保命指南!

春招数据显示传统开发岗位需求萎缩&#xff0c;AI相关岗位需求激增&#xff0c;但并非所有AI岗位都能受益。文章指出&#xff0c;初级开发、测试等执行型岗位面临淘汰风险&#xff0c;而定义问题、掌握核心技能的AI岗位则更受青睐。建议程序员从“执行者”向“定义者”转型&…

作者头像 李华
网站建设 2026/10/29 11:06:48

给问数平台开一个只读账号,我是这么把这条线焊死的

不替换原系统&#xff0c;只加问数入口&#xff0c;这句话落地靠一条底线&#xff0c;问数平台连的是一个只读账号。原系统照常记房源、记合同、记账单&#xff0c;问数平台连进去只能看&#xff0c;改不了也删不了。把这条线怎么焊死的过程记下来&#xff0c;给同样在接园区的…

作者头像 李华
网站建设 2026/10/29 11:06:45

learn-claude-code为什么会反复压缩上下文?一次已合并的 PR 实践

我给一个接近 8 万 Star 的开源项目提交了 PR&#xff0c;最近已经通过审核并合并&#xff01; 这个项目就是最近爆火的 learn-claude-code&#xff0c; 这次我主要对他的上下文压缩模块的snip_compact函数进行了修改&#xff0c;引入滞回阈值&#xff0c;给压缩操作留出缓冲&…

作者头像 李华
网站建设 2026/10/29 11:06:42

AI在软件测试的未来中处于什么位置?(2)

大家好&#xff0c;我是陈哥。 上次我们聊了AI对于测试领域的两项新技术&#xff0c;这周继续聊聊AI能帮我们做多少事。 这话听上去有点保守&#xff0c;我认为AI目前最有价值的位置其实是助手。AI真正的本事是让以前只能想想的自动化工具变得简单&#xff0c;或者说门槛一下子…

作者头像 李华