Registro de preguntas de algoritmo programación dinámica día 53 | 1143. Subsecuencia común más larga, 1035. Líneas disjuntas, 53. Suma máxima de subsecuencia

1143. Subsecuencia común más larga: LeetCode

Estado: AC después de ver la ecuación de transferencia.

Esta pregunta es una pregunta que se estudió durante el primer año de investigación, que es un ejemplo en la introducción a los algoritmos, la idea general es muy similar a la pregunta de ayer, la diferencia está en la ecuación de transferencia. Tenga en cuenta que también necesita saber cómo extraer esta subsecuencia común. El código se muestra a continuación:

class Solution {
public:
    int longestCommonSubsequence(string text1, string text2) {
        //dp[i][j] text1 i-1 和 text2 j-1 中的最大子序列长度
        int len1 = text1.size(), len2 = text2.size();
        vector<vector<int>> dp(len1+1, vector<int>(len2+1, 0));
        for(int i = 1; i <= len1; ++i){
            for(int j = 1; j <= len2; ++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[len1][len2];
    }
};

1035. Líneas disjuntas - LeetCode

Estado: AC tras comprobar las ideas.

La clave de esta pregunta es convertirla en el problema de subsecuencia común más largo de dos matrices. El código es el siguiente:

class Solution {
public:
    int maxUncrossedLines(vector<int>& nums1, vector<int>& nums2) {
        // 本质是找两个数组的最长公共子序列
        int len1 = nums1.size(), len2 = nums2.size();
        vector<vector<int>> dp(len1+1, vector<int>(len2+1, 0));
        for(int i = 1; i <= len1; ++i){
            for(int j = 1; j <= len2; ++j){
                if(nums1[i-1] == nums2[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[len1][len2];
    }
};

53. Suma máxima de subarreglo - LeetCode

Estado: CA.

He usado la idea codiciosa antes, pero la idea de programación dinámica es más fácil de pensar, preste atención al uso de res. El código se muestra a continuación:

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int len = nums.size();
        vector<int> dp(len, 0);
        dp[0] = nums[0];
        int res = nums[0];
        for(int i = 1; i < len; ++i){
            dp[i] = max(dp[i-1]+nums[i], nums[i]);
            if(dp[i] > res){ res = dp[i]; }
        }
        return res;
    }
};

 Impresión de subsecuencias/subcadenas públicas

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>

using namespace std;

class Solution{
public:
    // 最长公共子串
    string maxSubseq(string s1, string s2){
        int len1 = s1.size(), len2 = s2.size();
        vector<vector<int>> dp(len1+1, vector<int>(len2+1, 0));
        int res = INT_MIN, index = -1;
        for(int i = 1; i <= len1; ++i){
            for(int j = 1; j <= len2; ++j){
                if(s1[i-1] == s2[j-1]){
                    dp[i][j] = dp[i-1][j-1] + 1;
                }else{
                    dp[i][j] = 0;
                }
                if(dp[i][j] > res){
                    res = dp[i][j];
                    index = i;
                }
            }
        }
        return s1.substr(index-res, res);
    }

    // 最长公共子序列
    string maxComseq(string s1, string s2){
        int len1 = s1.size(), len2 = s2.size();
        vector<vector<int>> dp(len1+1, vector<int>(len2+1, 0));
        for(int i = 1; i <= len1; ++i){
            for(int j = 1; j <= len2; ++j){
                if(s1[i-1] == s2[j-1]){
                    dp[i][j] = dp[i-1][j-1] + 1;
                }else{
                    dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
                }
            }
        }
        string res = "";
        int i = len1, j = len2;
        while(i != 0 && j != 0){
            if(s1[i-1] == s2[j-1]){
                res += s1[i-1];
                i--;
                j--;
            }else if(dp[i-1][j] > dp[i][j-1]){
                i--;
            }else if(dp[i-1][j] <= dp[i][j-1]){
                j--;
            }
        }
        reverse(res.begin(), res.end());
        return res;
    }
};

int main()
{
    string s1 = "helloworld", s2 = "sawsogrlsdfa";
    Solution ans;
    string res1 = ans.maxSubseq(s1, s2);
    cout << res1 << endl;

    string res2 = ans.maxComseq(s1, s2);
    cout << res2 << endl;

    return 0;
}

Supongo que te gusta

Origin blog.csdn.net/qq_40395888/article/details/132634850
Recomendado
Clasificación