多维动态规划

多维动态规划

一.最长公共子序列

image

image

最长公共子序列问题:转移方程

 if(text1[i-1]==text2[j-1]){//当前位置相等
                dp[i][j]=dp[i-1][j-1]+1;
            }
            else{
                dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
            }

class Solution {
public:
    int longestCommonSubsequence(string text1, string text2) {
        //dp[i][j]表示text1的前i个字符里与text2的前j个字符能匹配的最长公共子序列
        int dp[1100][1100];
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=text1.size();i++){
         for(int j=1;j<=text2.size();j++){
            if(text1[i-1]==text2[j-1]){
                dp[i][j]=dp[i-1][j-1]+1;
            }
            else{
                dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
            }
         }
        }
        return dp[text1.size()][text2.size()];
    }
};

 二.回文子串问题

image

关键是:

枚举回文串长度len

然后转移方程:

dp[i][j]是否是回文串取决于s[i]是否等于s[j]且dp[i+1][j-1]是否为true

当且仅当两端相等s[i]==s[j]且两端间是回文串dp[i+1][j-1]==true时dp[i][j]为true

注意回文串为2单独判断因为没法i+1,j-1

要输出最长回文子串:只需要记录起点和串长就可以去截取

class Solution {
public:
    string longestPalindrome(string s) {
/*最长回文子串解法:
dp[i][j]表示s串中下标从i~j这段是否满足回文
       */
bool dp[1100][1100];
for(int i=0;i<1100;i++){
    for(int j=0;j<1100;j++){
        dp[i][j]=false;//默认不是回文
    }
}
for(int i=0;i<s.size();i++){//单个字符一定是回文
dp[i][i]=true;
}
//用起始下标和子串长来截取最长回文子序列
int start=0;
int l=1;
//最长回文序列通用操作
for(int len=2;len<=s.size();len++){//回文串长
for(int j=0;j+len-1<s.size();j++){//起点
    int end=j+len-1;//回文串终点
    if(s[j]==s[end]&&len==2){
          dp[j][end]=true;
        start=j;
        l=len;
        continue;
    }
    if(s[j]==s[end]&&dp[j+1][end-1]){
        dp[j][end]=true;
        start=j;
        l=len;
    }
}
}
return s.substr(start,l);
    }
};

 

问题三:编辑距离

image

image

class Solution {
public:
    int minDistance(string word1, string word2) {
        //思路有点类似于最长公共子序列
        /*
1.如果word1[i]=word2[j]则dp[i][j]=dp[i-1][j-1]
2.如果word1[i]!=word2[j]则有三种情况(都相当于做了一次操作)
(1)增加word1字符->等价于word2中删除当前的位置元素,1+dp[i][j-1]
(2)删除word1字符    1+dp[i-1][j]
(3)修改word1字符 等价于word1、word2都变    1+dp[i-1][j-1]

        */
        int dp[600][600];//dp[i][j]意思是word1的前i个字符与word2的前j个字符匹配所需要的最小变化数
        for(int i=0;i<600;i++){
            for(int j=0;j<600;j++){
                dp[i][j]=0;
            }
        }
        for(int i=1;i<=word1.size();i++){
            dp[i][0]=i;//非空串(word1)对应空串(word2中前0个字符)需要删i个字符
        }
       for(int j=1;j<=word2.size();j++){
        dp[0][j]=j;
       }
        for(int i=1;i<=word1.size();i++){
            for(int j=1;j<=word2.size();j++){
                if(word1[i-1]==word2[j-1]){
                    dp[i][j]=dp[i-1][j-1];
                }
                else{
                    dp[i][j]=1+min(min(dp[i][j-1],dp[i-1][j]),dp[i-1][j-1]);
                }
            }
        }
        return dp[word1.size()][word2.size()];
    }
};

 

posted @ 2025-08-23 01:28  Annaprincess  阅读(4)  评论(0)    收藏  举报