算法【更多二维动态规划题目】

news/2024/12/22 1:15:16/

本文不再从递归入手,而是直接从动态规划的定义入手,来解决更多二维动态规划问题。其中包含一些比较巧妙的尝试思路。

题目一

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

分析:dp数组的含义是字符串s前i个字符中出现字符串t前j个字符的次数。代码如下。

class Solution {
public:int dp[1001][1001];int MOD = 1000000007;int numDistinct(string s, string t) {int s_length = s.size();int t_length = t.size();dp[0][0] = 1;for(int i = 1;i <= t_length;++i){dp[0][i] = 0;}for(int i = 1;i <= s_length;++i){dp[i][0] = 1;}for(int i = 1;i <= s_length;++i){for(int j = 1;j <= t_length;++j){if(s[i-1] == t[j-1]){dp[i][j] = (dp[i-1][j-1] + dp[i-1][j]) % MOD;}else{dp[i][j] = dp[i-1][j];}}}return dp[s_length][t_length];}
};

从代码中可以看出做空间压缩很容易。代码如下。

class Solution {
public:int dp[1001];int leftup1, leftup2;int MOD = 1000000007;int numDistinct(string s, string t) {int s_length = s.size();int t_length = t.size();for(int i = 1;i <= t_length;++i){dp[i] = 0;}for(int i = 1;i <= s_length;++i){leftup1 = 1;for(int j = 1;j <= t_length;++j){leftup2 = dp[j];if(s[i-1] == t[j-1]){dp[j] = (leftup1 + dp[j]) % MOD;}leftup1 = leftup2;}}return dp[t_length];}
};

其中,辅助变量leftup含义和之前的文章一样。

题目二

测试链接:https://leetcode.cn/problems/edit-distance/

分析:dp数组含义为word1前i字符转换成word2前j个字符所使用的最少操作数。那么就有两种可能,一个是word1的最后一个字符参与变换,一个是word1的最后一个字符不参与变换。对于参与变换来说,一是这最后一个字符变为了word2的最后一个字符,二是最后一个字符变为了word2的倒数第二个字符,这word2的最后一个字符通过插入得到。对于不参与变换来说,次数为word1的前i-1个字符变换为word2的前j个字符的次数加上减去word1最后一个字符。这三种情况取最小值。代码如下。

class Solution {
public:int dp[501][501];int minDistance(string word1, string word2) {int word1_length = word1.size();int word2_length = word2.size();dp[0][0] = 0;for(int i = 1;i <= word2_length;++i){dp[0][i] = i;}for(int i = 1;i <= word1_length;++i){dp[i][0] = i;}for(int i = 1;i <= word1_length;++i){for(int j = 1;j <= word2_length;++j){if(word1[i-1] == word2[j-1]){dp[i][j] = dp[i-1][j-1];}else{dp[i][j] = dp[i-1][j-1]+1;}dp[i][j] = dp[i][j] < dp[i][j-1]+1 ? dp[i][j] : dp[i][j-1]+1;dp[i][j] = dp[i][j] < dp[i-1][j]+1 ? dp[i][j] : dp[i-1][j]+1;}}return dp[word1_length][word2_length];}
};

从代码中可以看出做空间压缩很容易。代码如下。

class Solution {
public:int dp[501];int leftup1, leftup2;int minDistance(string word1, string word2) {int word1_length = word1.size();int word2_length = word2.size();dp[0] = 0;for(int i = 1;i <= word2_length;++i){dp[i] = i;}for(int i = 1;i <= word1_length;++i){leftup1 = i-1;dp[0] = i;for(int j = 1;j <= word2_length;++j){leftup2 = dp[j];if(word1[i-1] == word2[j-1]){dp[j] = leftup1;}else{dp[j] = leftup1+1;}dp[j] = dp[j] < dp[j-1]+1 ? dp[j] : dp[j-1]+1;dp[j] = dp[j] < leftup2+1 ? dp[j] : leftup2+1;leftup1 = leftup2;}}return dp[word2_length];}
};

题目三

测试链接:https://leetcode.cn/problems/interleaving-string/

分析:dp数组的含义为s1的前i个字符和s2的前j个字符能否交错组成s3的前i+j个字符。代码如下。

class Solution {
public:bool dp[101][101] = {false};bool isInterleave(string s1, string s2, string s3) {int length_s1 = s1.size();int length_s2 = s2.size();int length_s3 = s3.size();if(length_s3 != length_s1 + length_s2){return false;}dp[0][0] = true;for(int i = 1;i <= length_s2;++i){dp[0][i] = dp[0][i-1] && s2[i-1] == s3[i-1];}for(int i = 1;i <= length_s1;++i){dp[i][0] = dp[i-1][0] && s1[i-1] == s3[i-1];}for(int i = 1;i <= length_s1;++i){for(int j = 1;j <= length_s2;++j){if(s3[i+j-1] == s1[i-1]){dp[i][j] |= dp[i-1][j];}if(s3[i+j-1] == s2[j-1]){dp[i][j] |= dp[i][j-1];}}}return dp[length_s1][length_s2];}
};

下面是做空间压缩的解法。代码如下。

class Solution {
public:bool dp[101] = {false};bool isInterleave(string s1, string s2, string s3) {int length_s1 = s1.size();int length_s2 = s2.size();int length_s3 = s3.size();if(length_s3 != length_s1 + length_s2){return false;}dp[0] = true;for(int i = 1;i <= length_s2;++i){dp[i] = dp[i-1] && s2[i-1] == s3[i-1];}bool temp;for(int i = 1;i <= length_s1;++i){dp[0] = dp[0] && s1[i-1] == s3[i-1];for(int j = 1;j <= length_s2;++j){temp = dp[j];dp[j] = false;if(s3[i+j-1] == s1[i-1]){dp[j] |= temp;}if(s3[i+j-1] == s2[j-1]){dp[j] |= dp[j-1];}}}return dp[length_s2];}
};

题目四

有效涂色问题

给定n、m两个参数

一共有n个格子,每个格子可以涂上一种颜色,颜色在m种里选

当涂满n个格子,并且m种颜色都使用了,叫一种有效方法

求一共有多少种有效的涂色方法

1 <= n, m <= 5000

结果比较大请 % 1000000007 之后返回

分析:dp数组的含义是i个格子j种颜色有多少种有效的涂色方法。代码如下。

#include <iostream>
#define MOD 1000000007
using namespace std;
int n, m;
int dp[5001][5001] = {0};
int main(void){scanf("%d%d", &n, &m);for(int i = 0;i <= n && i <= m;++i){dp[i][i] = 1;}for(int i = 1;i <= n;++i){dp[i][0] = 1;dp[i][1] = 1;}for(int i = 1;i <= n;++i){for(int j = 1;j <= m && i >= j;++j){dp[i][j] = (dp[i-1][j] * j + dp[i-1][j-1] * (m - j + 1)) % MOD;}}printf("%d", dp[n][m]);
}

题目五

删除至少几个字符可以变成另一个字符串的子串

给定两个字符串s1和s2

返回s1至少删除多少字符可以成为s2的子串

分析:这道题换个说法就非常简单了。我们只需要求出s1和s2的最长公共子序列,而s1至少删除多少字符可以成为s2的子串,就是s1的长度减去最长公共子序列的长度。而求最长公共子序列前面的文章中已经求过,这里不在给出代码。


http://www.ppmy.cn/news/1536681.html

相关文章

《RabbitMQ篇》消息应答和发布确认

消息应答 消息应答机制&#xff1a;消费者接收信息并处理完之后&#xff0c;告诉rabbitmq该信息已经处理&#xff0c;rabbitmq可以把该信息删除了. 消息自动重新入队&#xff1a;如果处理某个消息的消费者异常关闭了&#xff0c;没有发送ACK确认&#xff0c;rabbitmq会将其重…

抓包工具:Mitmproxy

Mitmproxy 是一组工具,它们为 HTTP/1、 HTTP/2和 WebSocket 提供交互式、支持 SSL/TLS 的拦截代理。 特性 拦截 HTTP 和 HTTPS 请求和响应并动态修改它们。 保存完整的 HTTP 对话,以便以后重放和分析。 重放 HTTP 会话的客户端。 重放以前记录的服务器的 HTTP 响应。 反向代…

信号用wire类型还是reg类型定义

wire类型就是一根线&#xff0c;线有两端&#xff0c;一端发生改变&#xff0c;经过线传递的信号当然也会发生改变&#xff0c;reg类型则不同&#xff0c;可以把reg类型理解为存储数据的寄存器&#xff0c;当满足一定条件时&#xff0c;数值才被激活发生改变。 那么&#xff0…

深入浅出React Hooks:打造高效、灵活的函数式组件

欢迎来到这本专注于React Hooks的小册!在这里,我们将深入探讨React生态系统中最强大、最灵活的特性之一 - Hooks。自2018年React 16.8版本引入以来,Hooks彻底改变了我们构建React应用的方式,为函数式组件注入了新的活力和能力。 本册涵盖了从基础到高级的47个精心挑选的Hooks,涉…

Pikachu-Sql Inject-宽字节注入

基本概念 宽字节是相对于ascII这样单字节而言的&#xff1b;像 GB2312、GBK、GB18030、BIG5、Shift_JIS 等这些都是常说的宽字节&#xff0c;实际上只有两字节 GBK 是一种多字符的编码&#xff0c;通常来说&#xff0c;一个 gbk 编码汉字&#xff0c;占用2个字节。一个…

Perforce演讲回顾(上):从UE项目Project Titan,看Helix Core在大型游戏开发中的版本控制与集成使用策略

日前&#xff0c;Perforce携手合作伙伴龙智一同亮相Unreal Fest 2024上海站&#xff0c;分享Helix Core版本控制系统及其协作套件的强大功能与最新动态&#xff0c;助力游戏创意产业加速前行。 Perforce解决方案工程师Kory Luo在活动主会场&#xff0c;带来《Perforce Helix C…

电子摄像头分割系统源码&数据集分享

电子摄像头分割系统源码&#xff06;数据集分享 [yolov8-seg-C2f-DWR&#xff06;yolov8-seg-C2f-ContextGuided等50全套改进创新点发刊_一键训练教程_Web前端展示] 1.研究背景与意义 项目参考ILSVRC ImageNet Large Scale Visual Recognition Challenge 项目来源AAAI Glob…

Axios 和 Ajax 的区别与联系

在前端开发中&#xff0c;数据的获取和交互是至关重要的环节。Axios 和 Ajax 都是常用的技术手段&#xff0c;用于实现与服务器的数据通信。本文将深入探讨 Axios 和 Ajax 的区别和联系&#xff0c;包括它们的特性、优缺点以及应用场景。 一、Axios 与 Ajax 的特性 Axios 的特…