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

算法【从递归入手一维动态规划】

动态规划:用空间代替重复计算,包含一整套原理和技巧的总和。后面会有非常多的文章介绍动态规划。

有些递归在展开计算时,总是重复调用同一个子问题的解,这种重复调用的递归变成动态规划很有收益。如果每次展开都是不同的解,或者重复调用的现象很少,那么没有改动态规划的必要。任何动态规划问题都一定对应着一个有重复调用行为的递归。所以任何动态规划的题目都一定可以从递归入手,逐渐实现动态规划的方法。尝试策略就是转移方程,完全一回事。推荐从尝试入手,因为代码好写,并且一旦发现尝试错误,重新想别的递归代价轻。

当熟悉了从递归到动态规划的转化过程,那么就可以纯粹用动态规划的视角来分析问题了。如果不熟悉这个过程,直接一上来就硬去理解状态转移方程,那么往往会步履维艰、邯郸学步、东施效颦。

动态规划的大致过程:想出设计优良的递归尝试(方法、经验、固定套路很多),有关尝试展开顺序的说明

-> 记忆化搜索(从顶到底的动态规划) ,如果每个状态的计算枚举代价很低,往往到这里就可以了。

-> 严格位置依赖的动态规划(从底到顶的动态规划) ,更多是为了下面说的进一步优化枚举做的准备。

-> 进一步优化空间(空间压缩),一维、二维、多维动态规划都存在这种优化。

-> 进一步优化枚举也就是优化时间(本文没有涉及,但是后续巨多内容和这有关)。

解决一个问题,可能有很多尝试方法,众多的尝试方法中,可能若干的尝试方法有重复调用的情况,可以转化成动态规划。若干个可以转化成动态规划的方法中,又可能有优劣之分。判定哪个是最优的动态规划方法,依据来自题目具体参数的数据量。最优的动态规划方法实现后,后续又有一整套的优化技巧。

下面通过一些题目入手动态规划。

题目一

测试链接:https://leetcode.cn/problems/fibonacci-number/

分析:斐波那契数是一个极其经典的动态规划问题。我们借由这个题目展开对动态规划的讨论,首先,我们使用一个递归暴力解法。代码如下。

class Solution {
public:int fib(int n) {if(n == 0){return 0;}else if(n == 1){return 1;}else{return fib(n-1) + fib(n-2);}}
};

其中,因为题目的数据量不大,所以递归暴力解法也能通过。下面使用记忆化搜索的解法,就是用一个数组把计算过的结果存储起来,以后要计算相同结果的时候直接使用。代码如下。

class Solution {
public:vector<int> record;int f(int n){if(n == 0){return 0;}if(n == 1){return 1;}if(record[n] != -1){return record[n];}int ans = f(n-1) + f(n-2);record[n] = ans;return ans;}int fib(int n) {record.assign(n+1, -1);return f(n);}
};

其中,对于f(n),如果record[n]不等于-1也就是计算过了,直接返回;如果等于-1,也就是并未计算出结果,就直接计算,然后将结果存入数组。记忆化搜索的解法已经很快了,接下来,我们看看严格位置依赖的解法,也就是普遍的动态规划。可以看出,f(n)的结果是依赖于f(n-1)和f(n-2),所以我们从前向后遍历dp数组,计算逻辑和递归以及记忆化搜索一样。代码如下。

class Solution {
public:vector<int> dp;int f(int n){if(n == 0){return 0;}if(n == 1){return 1;}dp[0] = 0;dp[1] = 1;for(int i = 2;i <= n;++i){dp[i] = dp[i-1] + dp[i-2];}return dp[n];}int fib(int n) {dp.assign(n+1, 0);return f(n);}
};

其中,将dp数组初始化后开始遍历dp数组计算结果。有了严格位置依赖的解法,我们可以从空间上去优化,也就是空间压缩。可以看出,dp[i]只依赖于dp[i-1]和dp[i-2],所以我们只需要用3个变量表示即可。代码如下。

class Solution {
public:int cur, last, lastLast;int f(int n){if(n == 0){return 0;}if(n == 1){return 1;}lastLast = 0;last = 1;for(int i = 2;i <= n;++i){cur = last + lastLast;lastLast = last;last = cur;}return cur;}int fib(int n) {return f(n);}
};

其中,cur表示dp[i],last表示dp[i-1],lastLast表示dp[i-2]。

题目二

测试链接:https://leetcode.cn/problems/minimum-cost-for-tickets/

分析:这个问题我们依然从递归解法开始,一步步推广到动态规划。f方法表示的意思是从下标为i的天数开始所需要的最小花费。因为纯递归暴力解法会超时,所以直接从记忆化搜索解法展示。代码如下。

class Solution {
public:vector<int> dp;int plan[3] = {1, 7, 30};int f(int i, vector<int>& days, vector<int>& costs){if(i >= days.size()){return 0;}if(dp[i] != -1){return dp[i];}int cur = days[i];int ans = -((1 << 31) + 1);int day, j;for(int p = 0;p < 3;++p){j = i + 1;day = plan[p];while (j < days.size() && cur + day > days[j]){++j;}ans = ans < costs[p]+f(j, days, costs) ? ans : costs[p]+f(j, days, costs);}dp[i] = ans;return ans;}int mincostTickets(vector<int>& days, vector<int>& costs) {dp.assign(366, -1);return f(0, days, costs);}
};

其中,递归主题思路是在当前天分别购买1、7、30天,然后从下一次需要购买的下标继续递归调用。记忆化搜索的解法只是比递归解法多了一个数组来存储结果,下面我们来看严格位置依赖的解法。可以看出,小下标依赖大下标的结果,所以从后向前遍历dp数组。代码如下。

class Solution {
public:int dp[366];int plan[3] = {1, 7, 30};int mincostTickets(vector<int>& days, vector<int>& costs) {int length = days.size();int cur, day, k;dp[length-1] = costs[0] < costs[1] ? (costs[0] < costs[2] ? costs[0] : costs[2]) : (costs[1] < costs[2] ? costs[1] : costs[2]);for(int i = length-2;i >= 0;--i){cur = days[i];dp[i] = costs[0] + dp[i+1];for(int j = 1;j < 3;++j){day = plan[j];k = i + 1;while (k < length && cur + day > days[k]){++k;}if(k == length){dp[i] = dp[i] < costs[j] ? dp[i] : costs[j];}else{dp[i] = dp[i] < costs[j]+dp[k] ? dp[i] : costs[j]+dp[k];}}}return dp[0];}
};

其中,计算逻辑和记忆化搜索相同。

题目三

测试链接:https://leetcode.cn/problems/decode-ways/

分析:这道题我们也先从记忆化搜索,也就是先从递归考虑尝试,然后再推广到严格位置依赖的解法。f方法表示,从下标i向后有多少种解码方法。代码如下。

class Solution {
public:vector<int> dp;int f(string s, int i){int ans;if(i >= s.size()){return 1;}if(dp[i] != -1){return dp[i];}if(s[i] == '0'){return 0;}ans = f(s, i+1);if(i+1 < s.size()&& ((s[i] == '1') || (s[i] == '2' && s[i+1] >= '0' && s[i+1] <= '6'))){ans += f(s, i+2);}dp[i] = ans;return ans;}int numDecodings(string s) {dp.assign(101, -1);return f(s, 0);}
};

其中,如果s[i]等于0则没有解码方法,如果有,先将s[i]单独划分成一个,然后再判断是否能讲s[i]和s[i+1]划分成一个。对于严格位置依赖的解法,我们可以看出小下标的结果依赖于大下标的结果,所以也是从后向前遍历dp数组,计算逻辑和记忆化搜索相同。代码如下。

class Solution {
public:int dp[101];int numDecodings(string s) {int length = s.size();dp[length] = 1;for(int i = length-1;i >= 0;--i){if(s[i] == '0'){dp[i] = 0;}else{dp[i] = dp[i+1];if(i+1 < length&& ((s[i] == '1') || (s[i] == '2' && s[i+1] >= '0' && s[i+1] <= '6'))){dp[i] += dp[i+2];}}}return dp[0];}
};

其中,计算完dp数组后dp[0]就是结果。再来从空间上压缩一下,这以看出i位置的结果依赖于i+1和i+2的结果,所以同样可以用三个变量来表示。代码如下。

class Solution {
public:int cur, next, nextNext;int numDecodings(string s) {int length = s.size();next = 1;for(int i = length-1;i >= 0;--i){if(s[i] == '0'){cur = 0;}else{cur = next;if(i+1 < length&& ((s[i] == '1') || (s[i] == '2' && s[i+1] >= '0' && s[i+1] <= '6'))){cur += nextNext;}}nextNext = next;next = cur;}return cur;}
};​

其中,cur表示dp[i],next表示dp[i+1],nextNext表示dp[i+2]。

题目四

测试链接:https://leetcode.cn/problems/decode-ways-ii/

分析:这道题和上道题思路差不多,只不过讨论的情况更多。同时,这道题如果使用记忆化搜索,会导致爆栈,所以只展示严格位置依赖的解法和空间压缩的解法。代码如下。

class Solution
{
public:int MOD = 1000000007;int dp[100002];int numDecodings(string s){int length = s.size();dp[length] = 1;for (int i = length - 1; i >= 0; --i){if (s[i] == '0'){dp[i] = 0;}else{if (s[i] > '0' && s[i] <= '9'){dp[i] = dp[i+1];}else{dp[i] = (9 * (long long)dp[i+1]) % MOD;}if (i + 1 < length){if (s[i] == '1' && s[i + 1] >= '0' && s[i + 1] <= '9'){dp[i] = (dp[i] + dp[i+2]) % MOD;}else if (s[i] == '2' && s[i + 1] >= '0' && s[i + 1] <= '6'){dp[i] = (dp[i] + dp[i+2]) % MOD;}else if (s[i] == '1' && s[i + 1] == '*'){dp[i] = (dp[i] + (9 * (long long)dp[i+2])) % MOD;}else if (s[i] == '2' && s[i + 1] == '*'){dp[i] = (dp[i] + (6 * (long long)dp[i+2])) % MOD;}else if (s[i] == '*' && s[i + 1] >= '0' && s[i + 1] <= '6'){dp[i] = (dp[i] + (2 * (long long)dp[i+2])) % MOD;}else if (s[i] == '*' && s[i + 1] > '6' && s[i + 1] <= '9'){dp[i] = (dp[i] + dp[i+2]) % MOD;}else if (s[i] == '*' && s[i + 1] == '*'){dp[i] = (dp[i] + (15 * (long long)dp[i+2])) % MOD;}}}}return dp[0];}
};

其中,和上道题一样,对于所有情况进行讨论,这里不再赘述。下面展示空间压缩的解法。代码如下。

class Solution
{
public:int MOD = 1000000007;int cur, next, nextNext;int numDecodings(string s){int length = s.size();next = 1;for (int i = length - 1; i >= 0; --i){if (s[i] == '0'){cur = 0;}else{if (s[i] > '0' && s[i] <= '9'){cur = next;}else{cur = (9 * (long long)next) % MOD;}if (i + 1 < length){if (s[i] == '1' && s[i + 1] >= '0' && s[i + 1] <= '9'){cur = (cur + nextNext) % MOD;}else if (s[i] == '2' && s[i + 1] >= '0' && s[i + 1] <= '6'){cur = (cur + nextNext) % MOD;}else if (s[i] == '1' && s[i + 1] == '*'){cur = (cur + (9 * (long long)nextNext)) % MOD;}else if (s[i] == '2' && s[i + 1] == '*'){cur = (cur + (6 * (long long)nextNext)) % MOD;}else if (s[i] == '*' && s[i + 1] >= '0' && s[i + 1] <= '6'){cur = (cur + (2 * (long long)nextNext)) % MOD;}else if (s[i] == '*' && s[i + 1] > '6' && s[i + 1] <= '9'){cur = (cur + nextNext) % MOD;}else if (s[i] == '*' && s[i + 1] == '*'){cur = (cur + (15 * (long long)nextNext)) % MOD;}}}nextNext = next;next = cur;}return cur;}
};

其中,cur,next,nextNext含义和上一题相同。

题目五

测试链接:https://leetcode.cn/problems/ugly-number-ii/

分析:现在我们就直接给出严格位置依赖的解法,不再对递归以及记忆化搜索的解法进行展示。对于丑数,可以知道1是第一个丑数。所以我们设置2指针,3指针和5指针,初始化指向第一个丑数也就是1。然后要得到后续的丑数时,将2指针指向的丑数乘以2,,3指针指向的丑数乘以3,,5指针指向的丑数乘以5,得到其中最小值就是当前的丑数。然后指针计算的结果小于等于得到丑数的,将指针后移指向下一个丑数。代码如下。

class Solution {
public:int dp[1692];int nthUglyNumber(int n) {if(n == 1){return 1;}int ptr_2 = 1, ptr_3 = 1, ptr_5 = 1, i = 2;dp[1] = 1;while (i <= n){dp[i] = dp[ptr_2] * 2 < dp[ptr_3] * 3 ?(dp[ptr_2] * 2 < dp[ptr_5] * 5 ? dp[ptr_2] * 2 : dp[ptr_5] * 5) :(dp[ptr_3] * 3 < dp[ptr_5] * 5 ? dp[ptr_3] * 3 : dp[ptr_5] * 5);if(dp[ptr_2] * 2 <= dp[i]){++ptr_2;}if(dp[ptr_3] * 3 <= dp[i]){++ptr_3;}if(dp[ptr_5] * 5 <= dp[i]){++ptr_5;}++i;}return dp[n];}
};

其中,通过一个嵌套的三目运算符来得到计算出的最小值。

题目六

测试链接:https://leetcode.cn/problems/longest-valid-parentheses/

分析:dp数组的含义是以下标i为结尾的有效子串最长长度。所以我们可以知道,当s[i]为左括号的时候,结果为dp[i]为0。当s[i]为右括号的时候开始讨论,设p是s[i-1]向左最长长度之后再左一个位置的下标,如果此时s[p]有效且s[p]为左括号则dp[i]=dp[i-1]+2,此时,如果p的左边仍然连接了一个有效的子串,则可以将这个子串的长度加上。遍历数组即可得到答案。代码如下。

class Solution {
public:int dp[30002] = {0};int longestValidParentheses(string s) {int length = s.size();int ans = 0;for(int i = 1, p;i < length;++i){if(s[i] == ')'){p = i - dp[i-1] - 1;if(p >= 0 && s[p] == '('){dp[i] = dp[i-1] + 2 + (p-1 >= 0 ? dp[p-1] : 0);}}ans = ans > dp[i] ? ans : dp[i];}return ans;}
};

其中,三目运算符就是在判断p左边是否还连接了一个有效子串。

题目七

测试链接:https://leetcode.cn/problems/unique-substrings-in-wraparound-string/

分析:对于这个题,我们可以先求得s串中以a到z字母为结尾的最长有序子串长度,这样可以避免重复计算结果,然后将每一个最长长度相加,即是答案。代码如下。

class Solution {
public:int longest[26] = {0};int findSubstringInWraproundString(string s) {int length = s.size();int len = 1;int ans = 0;longest[s[0]-'a'] = 1;for(int i = 1;i < length;++i){if((s[i] - s[i-1] + 26) % 26 == 1){longest[s[i]-'a'] = longest[s[i]-'a'] > ++len ? longest[s[i]-'a'] : len;}else{len = 1;longest[s[i]-'a'] = longest[s[i]-'a'] > 1 ? longest[s[i]-'a'] : 1;}}for(int i = 0;i < 26;++i){ans += longest[i];}return ans;}
};

其中,len就是s中到了下标i对于下标i字母为结尾的有序子串长度。

题目八

测试链接:https://leetcode.cn/problems/distinct-subsequences-ii/

分析:这个计算思路可以积累下来,十分好用。all代表当前集合数,初始化为1,代表1个空集,后面返回结果是减去;cur代表当前遍历到的字符;add代表新增的集合数目;nums数组存储以a到z字母为结尾的子序列数目。主要流程是:遍历到cur字符时,新增的不重复集合数目为all减去当前以cur为结尾的子序列数目,然后更新以cur为结尾的子序列的数目,更新当前集合数目。遍历完字符串即可得到答案。代码如下。

class Solution {
public:int nums[26] = {0};int MOD = 1000000007;int distinctSubseqII(string s) {int all = 1;int length = s.size();char cur;int add;for(int i = 0;i < length;++i){cur = s[i];add = (all - nums[cur-'a'] + MOD) % MOD;nums[cur-'a'] = (nums[cur-'a'] + add) % MOD;all = (all + add) % MOD;}return (all - 1 + MOD) % MOD;}
};

其中,因为数目过大采用同余原理处理结果。

相关文章:

算法【从递归入手一维动态规划】

动态规划&#xff1a;用空间代替重复计算&#xff0c;包含一整套原理和技巧的总和。后面会有非常多的文章介绍动态规划。 有些递归在展开计算时&#xff0c;总是重复调用同一个子问题的解&#xff0c;这种重复调用的递归变成动态规划很有收益。如果每次展开都是不同的解&#…...

Linux中的进程间通信之共享内存

共享内存 共享内存示意图 共享内存数据结构 struct shmid_ds {struct ipc_perm shm_perm; /* operation perms */int shm_segsz; /* size of segment (bytes) */__kernel_time_t shm_atime; /* last attach time */__kernel_time_t shm_dtime; /* last detach time */__kerne…...

第18周 3-过滤器

过滤器&#xff08;Filter&#xff09;概念总结 什么是过滤器 过滤器&#xff08;Filter&#xff09;是Java Web应用中用于统一拦截和处理请求的组件&#xff0c;类似于现实生活中的空气净化器或安检。它通过对请求进行前置处理&#xff0c;确保请求符合特定要求。 过滤器的…...

Linux之进程概念

作者主页&#xff1a; 作者主页 本篇博客专栏&#xff1a;Linux专栏 创作时间 &#xff1a;2024年9月28日 基本概念&#xff1a; 进程说白了其实就是一个程序的执行实例&#xff0c;正在执行的程序。 在内核层面来说&#xff0c;就是一个担当分配资源&#xff08;CPU时间…...

小程序-使用npm包

目录 Vant Weapp 安装 Vant 组件库 使用 Vant 组件 定制全局主题样式 API Promise化 1. 基于回调函数的异步 API 的缺点 2. 什么是 API Promise 化 3. 实现 API Promise 化 4.调用 Promise 化之后的异步 API 小程序对 npm 的支持与限制 目前&#xff0c;小程序中已经…...

【springboot】整合沙箱支付

目录 1. 配置沙箱应用环境2. 配置springboot项目1. 引入依赖2. 配置文件注册下载ngrok 3. 创建支付宝支付服务类4. 支付界面模板5. 控制类实现支付6. 测试 1. 配置沙箱应用环境 使用支付宝账号登录到开放平台控制台。 使用支付宝登录后&#xff0c;看到以下页面&#xff0c;下…...

技术速递|Python in Visual Studio Code 2024年9月发布

排版&#xff1a;Alan Wang 我们很高兴地宣布将于 2024 年 9 月发布适用于 Visual Studio Code 的 Python 和 Jupyter 扩展&#xff01; 此版本包括以下公告&#xff1a; Django 单元测试支持使用 Pylance 从 inlay 提示转到定义 如果您有兴趣&#xff0c;可以在我们的 Pyth…...

数据结构-3.5.队列的顺序实现

一.队列的顺序实现&#xff0c;初始化操作以及判断队列是否为空&#xff1a; 1.图解&#xff1a; 2.代码&#xff1a; #include<stdio.h> #define MaxSize 10 //定义一个队列最多存储的元素个数 ​ typedef struct {int data[MaxSize]; //用静态数组存放队列元素int f…...

preconnect 预解析

preconnect 是一种浏览器优化技术&#xff0c;用于告诉浏览器提前与指定的域名建立连接&#xff0c;包括DNS解析、TCP握手和TLS协商&#xff08;如果适用&#xff09;。这样做可以减少客户端在请求资源时所需的往返时间&#xff08;RTT&#xff09;&#xff0c;从而提高页面加载…...

Leecode热题100-283.移动零

给定一个数组 nums&#xff0c;编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。 请注意 &#xff0c;必须在不复制数组的情况下原地对数组进行操作。 示例 1: 输入: nums [0,1,0,3,12] 输出: [1,3,12,0,0]示例 2: 输入: nums [0] 输出: […...

如何高效使用Prompt与AI大模型对话

一、如何与人工智能对话 在人工智能的世界里&#xff0c;提示词&#xff08;Prompt&#xff09;就像是一把钥匙&#xff0c;能够解锁AI智能助手的潜力&#xff0c;帮助你更高效地获取信息、解决问题。但如何正确使用这把钥匙&#xff0c;却是一门艺术。本文将带你了解提示词的…...

Java 之深入理解 String、StringBuilder、StringBuffer

前言 由于发现 String、StringBuilder、StringBuffer 面试的时候会经常问到&#xff0c;这里就顺便总结一下&#xff1a;本文重点会以这三个字符串类的性能、线程安全、存储结构这三个方面进行分析 ✨上期回顾&#xff1a;Java 哈希表 ✨目录 前言 String 介绍 String 的不可变…...

vue3项目执行pnpm update后还原package.json文件后运行报错

项目场景&#xff1a; vue官方版本已更新到vue3.5&#xff0c;项目中还在使用vue3.4&#xff0c;因此想要更新项目vue版本。 问题描述 执行了 pnpm update 命令&#xff0c;一键更新了所有包&#xff0c;更新完成后项目不能正常运行。为了还原项目代码&#xff0c;先删除 nod…...

蓝桥杯【物联网】零基础到国奖之路:十七. 扩展模块之单路ADC和NE555

蓝桥杯【物联网】零基础到国奖之路:十七. 扩展模块之单路ADC和NE555 第一节 硬件解读第二节 CubeMx配置第三节 代码1&#xff0c;脉冲部分代码2&#xff0c;ADC部分代码![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/57531a4ee76d46daa227ae0a52993191.png) 第一节 …...

SolveigMM Video Splitter方便快捷视频分割合并软件 V3.6.1309.3-供大家学习研究参考

视频分割功能(Splitter)支持各种编码格式的AVI(DivX、DV、MJPEG、XVID、MPEG-4)、WMV、ASF(DivX、MJPEG、XVID、MPEG-4、WM Video 7/9)F、MPEG(*.mpg、*.mpeg、*.mpv、*.m2v、*.vob)文件、也支持受损的WMV、ASF格式的分割。视频合并功能(Joiner)则支持AVI、WMV/ASF、WMA、MP3、…...

Unity3D 创建一个人物,实现人物的移动

1&#xff0c;创建项目 首先打开我们的Unity Hub 在我们的编译器下面新建项目&#xff0c;选择3D模板&#xff0c;更改一下我们的项目名称&#xff0c;选择一下路径&#xff0c;然后点击创建项目 等待项目创建。。。。。。 我们在项目里先创建一个plane&#xff0c;这样有点视…...

【笔记】数据结构12

文章目录 2013年408应用题41方法一方法二 看到的社区的一个知识总结&#xff0c;这里记录一下。 知识点汇总 2013年408应用题41 解决方法&#xff1a; 方法一 &#xff08;1&#xff09;算法思想 算法的策略是从前向后扫描数组元素&#xff0c;标记出一个可能成为主元素的元…...

django的URL配置

1 django如何处理一个请求 首先Django要使用根URLconf模块&#xff0c;通过setting.py配置文件的ROOT_URLCONF来设置。 加载该模块后并查找变量 urlpatterns。这是一个Python的django.conf.urls.url()实例列表。 Django按顺序运行每个URL模式&#xff0c;并在匹配所请求的…...

精华帖分享 | 因子构建思考1

本文来源于量化小论坛股票量化板块精华帖&#xff0c;作者为z-coffee。 以下为精华帖正文&#xff1a; 一段时间没写帖子&#xff0c;其实一直在研究策略&#xff0c;只是从不同的角度去思考而已。熟悉我的老板其实清楚&#xff0c;我的炉子水平一般&#xff0c;基本不太依托…...

kubernetes笔记(四)

一、Pod调度策略 1.基于节点的调度 spec->nodeName [rootmaster ~]# vim myhttp.yaml --- kind: Pod apiVersion: v1 metadata:name: myhttp spec:nodeName: node-0001 # 基于节点名称进行调度containers:- name: apacheimage: myos:httpd[rootmaster ~]# kubectl a…...

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...

rknn优化教程(二)

文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK&#xff0c;开始写第二篇的内容了。这篇博客主要能写一下&#xff1a; 如何给一些三方库按照xmake方式进行封装&#xff0c;供调用如何按…...

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...

Unity3D中Gfx.WaitForPresent优化方案

前言 在Unity中&#xff0c;Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染&#xff08;即CPU被阻塞&#xff09;&#xff0c;这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案&#xff1a; 对惹&#xff0c;这里有一个游戏开发交流小组&…...

MFC内存泄露

1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...

Day131 | 灵神 | 回溯算法 | 子集型 子集

Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 笔者写过很多次这道题了&#xff0c;不想写题解了&#xff0c;大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...

STM32标准库-DMA直接存储器存取

文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA&#xff08;Direct Memory Access&#xff09;直接存储器存取 DMA可以提供外设…...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

scikit-learn机器学习

# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...