首页 > 其他分享 >Day49 | 动态规划 :线性DP 判断子序列&&两个字符串的删除操作

Day49 | 动态规划 :线性DP 判断子序列&&两个字符串的删除操作

时间:2024-11-28 16:33:04浏览次数:9  
标签:&& int string dfs vector dp Day49 DP size

Day49 | 动态规划 :线性DP 判断子序列&&两个字符串的删除操作

动态规划应该如何学习?-CSDN博客

动态规划学习:

1.思考回溯法(深度优先遍历)怎么写

注意要画树形结构图

2.转成记忆化搜索

看哪些地方是重复计算的,怎么用记忆化搜索给顶替掉这些重复计算

3.把记忆化搜索翻译成动态规划

基本就是1:1转换

文章目录

392.判断子序列

392. 判断子序列 - 力扣(LeetCode)

思路分析(子问题):

就是昨天的编辑距离的删除操作Day48 | 动态规划 :线性DP 编辑距离-CSDN博客

dfs(x,y)就是s的前x个字符是不是t的前y个字符的子序列,是返回true,不是返回false

x为s的下标,y为t的下标

还是看选或不选s[x]和t[y]

1.如果s[x]==t[y]

那就选s[x]和t[y]

返回dfs(x-1,y-1),继续递归下面的,即

dfs(x,y)=dfs(x-1,y-1)

也可以理解为当前的s[x]和t[y]对结果没有影响

2.如果s[x]!=t[y]

那就是删除掉t[y]看t剩下的部分包不包含s

dfs(x,y)=dfs(x,y-1)

递归边界

如果s为空串,那一定是t的子序列,返回true

如果t为空串,那s不管怎么样都不会是t的子序列,返回false

1.回溯

class Solution {
public:
    bool dfs(int i,int j,string &s,string &t)
    {
        if(i<0)
            return true;
        if(j<0)
            return false;
        if(s[i]==t[j])
            return dfs(i-1,j-1,s,t);
        else
            return dfs(i,j-1,s,t);
    }
    bool isSubsequence(string s, string t) {
        return dfs(s.size()-1,t.size()-1,s,t);
    }
};

2.记忆化搜索

就是搞一个哈希表dp,全都初始化为-1,每次返回前给哈希表dp赋值,碰到不是-1的那就是算过的,那就直接返回计算过的结果,不需要再次递归了

class Solution {
public:
    bool dfs(int i,int j,string &s,string &t,vector<vector<int>> &dp)
    {
        if(i<0)
            return true;
        if(j<0)
            return false;
        if(dp[i][j]!=-1)
            return dp[i][j];
        if(s[i]==t[j])
            return dp[i][j]=dfs(i-1,j-1,s,t,dp);
        else
            return dp[i][j]=dfs(i,j-1,s,t,dp);
    }
    bool isSubsequence(string s, string t) {
        vector<vector<int>> dp(s.size(),vector<int>(t.size(),-1));
        return dfs(s.size()-1,t.size()-1,s,t,dp);
    }
};

3.动态规划

注意我们的i=0和j=0是表示的dfs中i<0和j<0非法的状态,即s为空串或者t为空串,对应的是递归边界

所以dp数组的下标从1开始记录答案

class Solution {
public:
    bool isSubsequence(string s, string t) {
        vector<vector<bool>> dp(s.size()+1,vector<bool>(t.size()+1,false));
        for(int i=0;i<=t.size();i++)
            dp[0][i]=true;
        for(int i=0;i<s.size();i++)
            for(int j=0;j<t.size();j++)
                if(s[i]==t[j])
                    dp[i+1][j+1]=dp[i][j];
                else    
                    dp[i+1][j+1]=dp[i+1][j];
        return dp[s.size()][t.size()];
    }
};

583.两个字符串的删除操作

583. 两个字符串的删除操作 - 力扣(LeetCode)

思路分析(子问题):

就是昨天的编辑距离的删除操作Day48 | 动态规划 :线性DP 编辑距离-CSDN博客

//相等不用删		
if(s[i]==t[j])
	return dfs(i-1,j-1,s,t);
//不相等
else
	return min(dfs(i-1,j,s,t),dfs(i,j-1,s,t))+1;
//               删s的            删t的
//两个里面搞一个最小值最后再把删除这一步的步数1加上搞定

仅仅是去掉了替换操作,剩下的代码都一样的,这里不做过多的解释了

1.回溯

class Solution {
public:
    int dfs(int i,int j,string& s,string &t)
    {
        if(i<0)
            return j+1;
        if(j<0)
            return i+1;
        if(s[i]==t[j])
            return dfs(i-1,j-1,s,t);
        else
            return min(dfs(i-1,j,s,t),dfs(i,j-1,s,t))+1;
    }
    int minDistance(string word1, string word2) {
        return dfs(word1.size()-1,word2.size()-1,word1,word2);        
    }
};

2.记忆化搜索

就是搞一个哈希表dp,全都初始化为-1,每次返回前给哈希表dp赋值,碰到不是-1的那就是算过的,那就直接返回计算过的结果,不需要再次递归了

class Solution {
public:
    int dfs(int i,int j,string& s,string &t,vector<vector<int>> &dp)
    {
        if(i<0)
            return j+1;
        if(j<0)
            return i+1;
        if(dp[i][j]!=-1)
            return dp[i][j];
        if(s[i]==t[j])
            return dp[i][j]=dfs(i-1,j-1,s,t,dp);
        else
            return dp[i][j]=min(dfs(i-1,j,s,t,dp),dfs(i,j-1,s,t,dp))+1;
    }
    int minDistance(string word1, string word2) {
        vector<vector<int>> dp(word1.size(),vector<int>(word2.size(),-1));
        return dfs(word1.size()-1,word2.size()-1,word1,word2,dp);        
    }
};

3.动态规划

注意我们的i=0和j=0是表示的dfs中i<0和j<0非法的状态,即s为空串或者t为空串,对应的是递归边界

所以dp数组的下标从1开始记录答案

class Solution {
public:
    int minDistance(string word1, string word2) {
        vector<vector<int>> dp(word1.size()+1,vector<int>(word2.size()+1,0));
        for(int i=0;i<=word2.size();i++)
            dp[0][i]=i;
        for(int i=0;i<=word1.size();i++)
            dp[i][0]=i;
        for(int i=0;i<word1.size();i++)
            for(int j=0;j<word2.size();j++)
                if(word1[i]==word2[j])
                    dp[i+1][j+1]=dp[i][j];
                else
                    dp[i+1][j+1]=min(dp[i+1][j],dp[i][j+1])+1;
        return dp[word1.size()][word2.size()];        
    }
};

标签:&&,int,string,dfs,vector,dp,Day49,DP,size
From: https://blog.csdn.net/m0_74795952/article/details/144088217

相关文章

  • 不会贪心和 dp 啊(utpc2021 E)
    luogu/pjudge题意:\(n\)个点,权值\(x,y,c\),选\(m\)个,\(S\)为选出的集合。最大化\(\maxp_x-\minp_x+\maxp_y-\minp_y+\sump_c(p\inS)\)\(n,m\le2e5\)这是蓝。这是蓝。这是蓝。如此水平,令人汗颜!有一个重要的性质:当\(m\gt4\)时,按c排序后前\(m-4\)大的一定会......
  • Python 使用shapely、geopandas、matplotlib绘制全国各个省份2023年GDP热力图,鼠标点击
    以下是一个示例代码,用于在使用matplotlib和geopandas绘制地图并设置区域后,当鼠标点击地图上的某个区域时,返回该区域的名称。首先,确保你已经安装了matplotlib、geopandas和descartes库(descartes库用于在matplotlib中绘制地理空间数据)。如果没有安装,可以通过pipinstallmatplot......
  • P10974 换根 dp 解题报告
    题目传送门题目大意:给定一颗无根树,有一个节点是源点,度数为\(1\)的点是汇点,树上的边有最大流量。除源点和汇点外,其它点不储存水,即流入该点的水量之和等于从该点流出的水量之和。整个水系的流量定义为原点单位时间内能发出的水量。现在需要求出:在流量不超过最大流量的前提下,选......
  • DP 套 DP 与 游园会
    DP套DP听名字猜不到它是个什么东西。接下来用一道例题P459TJOI2018游园会来解释DP套DP。游园会参考资料。题目描述小豆参加了NOI的游园会,会场上每完成一个项目就会获得一个奖章,奖章只会是\(\texttt{N}\)、\(\texttt{O}\)、\(\texttt{I}\)的字样。在会场上他......
  • NOIP 冲刺之——dp
    \(\texttt{0x00}\)前言本篇文章主要记录笔者NOIP冲刺阶段复习的各种dp题型及tricksanstips,同时也用于及时复习与巩固。那么,开始吧。\(\texttt{0x01}\)线性dp线性dp对我来说是一类很捉摸不定的题型:她太综合了,可以和任何知识点合起来考,这里就先抛开“数据结构优化”......
  • 动态规划 区间dp 基础题
    题目19182石子合并(基础版)时间限制:1000MS代码长度限制:10KB提交次数:0通过次数:0题型:编程题语言:不限定Description设有N(N≤300)堆石子排成一排,其编号为1,2,3,⋯,N。每堆石子有一定的质量mi(mi≤1000)。现在要将这N堆石子合并成为一堆。每次只能合并相邻的两堆,......
  • jmeter测试udp接口详解
    jmeter测试udp广播(jmeter发送udp)jmeter测试udp广播(jmeter接收udp)先下载安装第三方插件下载链接:https://jmeter-plugins.org/install/Install/ 将下载的插件放在lib/ext目录里面 然后重启jmeter,如下图操作:          此时可以看到lib/ext目录里面多了......
  • 【DP优化技巧】2. 矩阵加快
    例题来看一道例题。P5024[NOIP2018提高组]保卫王国对于这道题,首先如果没有国王的询问,可以设定状态:\(f_{i,0/1}\)代表以\(i\)为根的子树里面,自己选/不选的最小花费。易得状态转移方程:\[f_{u,0}=\sum_{v\inson_u}f_{v,1}\\f_{u,1}=p_u+\sum_{v\inson_u}\min(f_{v,0},......
  • 数据结构优化DP
    数据结构优化DP参考题单CleaningShiftsS区间覆盖问题区间加区间最值线段树维护cin>>n>>m>>e;m++,e++;for(inti=1;i<=n;i++) c[i].in();T.build(1,1,e);sort(c+1,c+1+n,[](nodea,nodeb){ if(a.l==b.l)returna.r<b.r; returna......
  • 嵌入式开发之UDP网络编程
    1、TCP编程的函数API1.1、网络发送数据:send()/write()#include<sys/types.h>#include<sys/socket.h>ssize_tsend(intsockfd,constvoid*buf,size_tlen,intflags);#include<unistd.h>ssize_twrite(intfd,constvoid*buf,size_tcount);send()比write多......