二维动态规划2

[Algo] 二维动态规划2

1. 不同的子序列

// 4. 不同的子序列
// https://leetcode.cn/problems/distinct-subsequences/
long numDistinct(string s, string t) {
    int n = s.length(), m = t.length();
    vector<vector<long>> dp(n + 1, vector<long>(m + 1)); // dp[i][j] - s[0...i-1]中包含子序列t[0...j-1]的个数
    // 状态转移方程 - dp[i][j] = dp[i - 1][j] + dp[i - 1][j - 1](s[i - 1] == t[j - 1])
    for (int i = 0; i <= n; i++) dp[i][0] = 1;
    for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++)
    dp[i][j] = (dp[i - 1][j] + (s[i - 1] == t[j - 1] ? dp[i - 1][j - 1] : 0)) % MOD;
    return dp[n][m];
}
long numDistinct_(string s, string t) {
    int n = s.length(), m = t.length();
    vector<long> dp(m + 1);
    dp[0] = 1;
    for (int i = 1; i <= n; i++) for (int j = m; j >= 1; j--)
    if (s[i - 1] == t[j - 1]) dp[j] = (dp[j] + dp[j - 1]) % MOD;
    return dp[m];
}

2. 编辑距离

// 5. 编辑距离
// https://leetcode.cn/problems/edit-distance/
// 插入一个字符,代价a
// 删除一个字符,代价b
// 替换一个字符,代价c
int MinDistance(string word1, string word2, int a, int b, int c) {
    int n = word1.length(), m = word2.length();
    vector<vector<int>> dp(n + 1, vector<int>(m + 1));
    // 状态转移方程 - (1)word1[i - 1] == word2[j - 1], dp[i][j] = dp[i - 1][j - 1]
    //              (2)word1[i - 1] != word2[j - 1], dp[i][j] = min(dp[i - 1][j - 1] + c, dp[i][j - 1] + a, dp[i - 1][j] + b)
    for (int j = 1; j <= m; j++) dp[0][j] = j * a;
    for (int i = 1; i <= n; i++) dp[i][0] = i * b;
    for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++)
    if (word1[i - 1] == word2[j - 1]) dp[i][j] = dp[i - 1][j - 1];
    else dp[i][j] = min(min(dp[i - 1][j - 1] + c, dp[i][j - 1] + a), dp[i - 1][j] + b);
    return dp[n][m];
}

3. 交错字符串

// 6. 交错字符串
// https://leetcode.cn/problems/interleaving-string/
bool isInterleave(string s1, string s2, string s3) {
    int n = s1.length(), m = s2.length(), k = s3.length();
    if (n + m != k) return false;
    vector<vector<bool>> dp(n + 1, vector<bool>(m + 1, false)); // dp[i][j] - s1[0...i-1]与s2[0...j-1]能否拼出s3[0...i+j-1]
    // 状态转移方程 - (1)s1[i - 1] == s3[i + j - 1], dp[i - 1][j]
    //              (2)s2[j - 1] == s3[i + j - 1], dp[i][j - 1]
    dp[0][0] = true;
    for (int j = 1; j <= m; j++)
    {
        if (s2[j - 1] != s3[j - 1]) break;
        dp[0][j] = true;
    }
    for (int i = 1; i <= n; i++)
    {
        if (s1[i - 1] != s3[i - 1]) break;
        dp[i][0] = true;
    }
    for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++)
    dp[i][j] = (s1[i - 1] == s3[i + j - 1] && dp[i - 1][j]) || (s2[j - 1] == s3[i + j - 1] && dp[i][j - 1]);
    return dp[n][m];
}
posted @   yaoguyuan  阅读(1)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)
· AI 智能体引爆开源社区「GitHub 热点速览」
点击右上角即可分享
微信分享提示