首页 > 其他分享 >二维动态规划

二维动态规划

时间:2025-01-07 17:33:52浏览次数:1  
标签:return int len1 len2 二维 grid 动态 规划 dp

[Algo] 二维动态规划

fx1 - 暴力递归, fx2 - 记忆化搜索, fx3 - 严格位置依赖, fx4 - 状态压缩

1. 最小路径和

// 1. 最小路径和
// https://leetcode.cn/problems/minimum-path-sum/description/
int f11(vector<vector<int>>& grid, int i, int j)
{
    int n = grid.size(), m = grid[0].size();
    if (i == n - 1 && j == m - 1) return grid[i][j];
    int down = i + 1 >= n ? INT32_MAX : f11(grid, i + 1, j);
    int right = j + 1 >= m ? INT32_MAX : f11(grid, i, j + 1);
    return grid[i][j] + min(down, right);
}
int f12(vector<vector<int>>& grid, int i, int j, vector<vector<int>>& mem)
{
    int n = grid.size(), m = grid[0].size();
    if (mem[i][j] != -1) return mem[i][j];
    int ans;
    if (i == n - 1 && j == m - 1) ans = grid[i][j];
    else
    {
        int down = i + 1 >= n ? INT32_MAX : f12(grid, i + 1, j, mem);
        int right = j + 1 >= m ? INT32_MAX : f12(grid, i, j + 1, mem);
        ans = grid[i][j] + min(down, right);
    }
    mem[i][j] = ans;
    return ans;
}
int f13(vector<vector<int>>& grid, vector<vector<int>>& dp)
{
    // 每个格子依赖右边和下面的格子,因此从下往上,从右往左依次填充dp表
    int n = grid.size(), m = grid[0].size();
    dp[n - 1][m - 1] = grid[n - 1][m - 1];
    for (int j = m - 2; j >= 0; j--) dp[n - 1][j] = dp[n - 1][j + 1] + grid[n - 1][j];
    for (int i = n - 2; i >= 0; i--) dp[i][m - 1] = dp[i + 1][m - 1] + grid[i][m - 1];
    for (int i = n - 2; i >= 0; i--)
    for (int j = m - 2; j >= 0; j--) dp[i][j] = grid[i][j] + min(dp[i + 1][j], dp[i][j + 1]);
    return dp[0][0];
}
int f14(vector<vector<int>>& grid, vector<int>& dp)
{
    // 根据位置依赖关系,dp表可以压缩成单行
    int n = grid.size(), m = grid[0].size();
    dp[m - 1] = grid[n - 1][m - 1];
    for (int j = m - 2; j >= 0; j--) dp[j] = dp[j + 1] + grid[n - 1][j];
    for (int i = n - 2; i >= 0; i--)
    {
        dp[m - 1] = dp[m - 1] + grid[i][m - 1];
        for (int j = m - 2; j >= 0; j--) dp[j] = grid[i][j] + min(dp[j], dp[j + 1]);
    }
    return dp[0];
}
int minPathSum(vector<vector<int>>& grid) {
    int n = grid.size(), m = grid[0].size();
    vector<int> dp(m);
    return f14(grid, dp);
}

2. 最长公共子序列

// 2. 最长公共子序列
// https://leetcode.cn/problems/longest-common-subsequence/description/
int f21(string &s1, string &s2, int len1, int len2)
{
    if (len1 == 0 || len2 == 0) return 0;
    if (s1[len1 - 1] == s2[len2 - 1]) return 1 + f21(s1, s2, len1 - 1, len2 - 1);
    else return max(f21(s1, s2, len1 - 1, len2), f21(s1, s2, len1, len2 - 1));
}
int f22(string &s1, string &s2, int len1, int len2, vector<vector<int>> &mem)
{
    if (mem[len1][len2] != -1) return mem[len1][len2];
    int ans;
    if (len1 == 0 || len2 == 0) ans = 0;
    else if (s1[len1 - 1] == s2[len2 - 1]) ans = 1 + f22(s1, s2, len1 - 1, len2 - 1, mem);
    else ans = max(f22(s1, s2, len1 - 1, len2, mem), f22(s1, s2, len1, len2 - 1, mem));
    mem[len1][len2] = ans;
    return ans;
}
int f23(string &s1, string &s2, vector<vector<int>> &dp)
{
    // 每个格子依赖左边、上面和左上的三个格子,因此从上往下,从左往右填充dp表
    int len1 = s1.length(), len2 = s2.length();
    for (int i = 1; i <= len1; i++)
    for (int j = 1; j <= len2; j++)
    {
        if (s1[i - 1] == s2[j - 1]) dp[i][j] = 1 + dp[i - 1][j - 1];
        else dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
    }
    return dp[len1][len2];
}
int f24(string &s1, string &s2, vector<int> &dp)
{
    // 由于每个格子除了依赖左边和上面的格子外,还需要依赖左上的格子,因此需要多用一个变量leftup保存左上的值
    int len1 = s1.length(), len2 = s2.length();
    for (int i = 1; i <= len1; i++)
    {
        int leftup = 0, tmp;
        for (int j = 1; j <= len2; j++)
        {
            tmp = dp[j];
            if (s1[i - 1] == s2[j - 1]) dp[j] = 1 + leftup;
            else dp[j] = max(dp[j - 1], dp[j]);
            leftup = tmp;
        }
    }
    return dp[len2];
}
int longestCommonSubsequence(string text1, string text2) {
    int len1 = text1.length(), len2 = text2.length();
    if (len1 < len2)
    {
        vector<int> dp(len1 + 1);
        return f24(text2, text1, dp);
    }
    else
    {
        vector<int> dp(len2 + 1);
        return f24(text1, text2, dp);
    }
}

3. 节点数为n高度不大于m的二叉树个数

// 3. 节点数为n高度不大于m的二叉树个数
// https://www.nowcoder.com/practice/aaefe5896cce4204b276e213e725f3ea
long f31(int n, int m)
{
    if (n == 0) return 1;
    if (m == 0) return 0;
    // n > 0, m > 0
    long ans = 0;
    for (int k = 0; k <= n - 1; k++) ans = (ans + (f31(k, m - 1) * f31(n - 1 - k, m - 1)) % MOD) % MOD;
    return ans;
}
long f32(int n, int m, vector<vector<long>> &mem)
{
    if (mem[n][m] != -1) return mem[n][m];
    long ans = 0;
    if (n == 0) ans = 1;
    else if (m == 0) ans = 0;
    // n > 0, m > 0
    else for (int k = 0; k <= n - 1; k++) ans = (ans + (f32(k, m - 1, mem) * f32(n - 1 - k, m - 1, mem)) % MOD) % MOD;
    mem[n][m] = ans;
    return ans;
}
long f33(int n, int m, vector<vector<long>> &dp)
{
    for (int j = 0; j <= m; j++) dp[0][j] = 1;
    for (int i = 1; i <= n; i++) dp[i][0] = 0;
    for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++)
    for (int k = 0; k <= i - 1; k++)
    dp[i][j] = (dp[i][j] + (dp[k][j - 1] * dp[i - 1 - k][j - 1]) % MOD) % MOD;
    return dp[n][m];
}
long f34(int n, int m, vector<long> &dp)
{
    dp[0] = 1;
    for (int j = 1; j <= m; j++)
    for (int i = n; i >= 1; i--)
    {
        dp[i] = 0; // !!!
        for (int k = 0; k <= i - 1; k++)
        dp[i] = (dp[i] + (dp[k] * dp[i - 1 - k]) % MOD) % MOD;
    }
    return dp[n];
}
int numberOfBinaryTree(int n, int m)
{
    vector<long> dp(n + 1);
    return f34(n, m, dp);
}

标签:return,int,len1,len2,二维,grid,动态,规划,dp
From: https://www.cnblogs.com/yaoguyuan/p/18658024

相关文章

  • 一维动态规划
    [Algo]一维动态规划fx1-暴力递归,fx2-自顶向底动态规划(记忆化搜索),fx3-自底向顶动态规划(严格位置依赖)1.最低票价//1.最低票价//https://leetcode.cn/problems/minimum-cost-for-tickets/description/intduration[3]={1,7,30};intf11(vector<int>&da......
  • C语言实现通讯录(动态的版本)
    通讯录的实现框架动态的版本通讯录默认能存放3个人的信息如果空间不够了,就增加空间,每次增加2个人的空间实现一个通讯录:人的信息:名字+年龄+性别+电话+地址1.增加联系人2.删除指定联系人3.查找联系人4.修改联系人5.显示联系人6.排序测试功能test.c......
  • DLL侧载(DLL Side-Loading) 是一种攻击技术,通常被黑客利用来执行恶意代码。它发生在应用
    DLL侧载(DLLSide-Loading)是一种攻击技术,通常被黑客利用来执行恶意代码。它发生在应用程序加载动态链接库(DLL)文件时,攻击者通过某些手段将恶意的DLL文件植入到应用程序的正常路径或不受限制的目录中,从而欺骗操作系统或应用程序加载恶意DLL,导致执行攻击者控制的代码。1. 什么是DLL......
  • 76页智能工厂规划及实施案例学习智能工厂规划
        智能工厂规划及实施中,综合布线系统作为核心基础设施,扮演着至关重要的角色。该系统以标准化、统一化、简化的方式,精心布置建筑物内外的通信网络,涵盖网络、电话、监控、电源及照明等多个子系统,确保信息传输的高效与稳定。综合布线不仅是物理线路的集合,更是智慧工厂信......
  • xxl_job系列---【Glue(java)模式如何通过动态参数传参?】
    1.编辑GLUE(Java)模式的定时任务这里以传递json参数为例:修改任务参数:{"startDate":"","endDate":"","desc":"入参日期格式:yyyyMMdd"}保存。2.编辑此定时任务的GLUE脚本import添加:importcom.xxl.job.core.context.XxlJobHelper;importcn.hutool......
  • 杨辉三角(动态规划)
    给定一个非负整数 numRows,生成「杨辉三角」的前 numRows 行。在「杨辉三角」中,每个数是它左上方和右上方的数的和。 示例1:输入:numRows=5输出:[[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]]示例 2:输入:numRows=1输出:[[1]] classSolution{public:......
  • [SMARTFORMS] 创建二维码
    我们可以使用事务码SE73创建二维码选择系统条形码,点击"更改"按钮点击 创建选项 选择"新"输入二维码名称和简短描述,点击"确认"按钮选择"QRCODE2005",点击"确认"按钮选择"Normal",点击"确认"按钮ModuleSize 可设置生成的二维码的大小后续的操作直接全部按照......
  • 简易动态进程池
    /************proto.h********************/#ifndef__PROTO_H__#define__PROTO_H__#defineFORMAT "%ld\n"#defineMINIDLEPROCNUM 5#defineMAXIDLEPROCNUM 10#defineMAXPROCNUM 20#defineSERVERPORT "4096"#endif /************se......
  • ITSM落地经验之建设蓝图规划
    ITSM的规划建设不同于数字化转型规划,更多体现在管理中基本要素变革的规划,传统的ITSM规划重点在于流程规划。在过去,结合大部分客户实施ITSM效果较差或失败的现象来看,这些组织往往忽略了对组织文化与管理实践的诊断和规划,我们的建议在规划阶段充分对流程、文化、管理实践的现状进行......
  • WXML (微信小程序模板) 代码,用于根据 item.key 的值动态添加 CSS 类名,从而实现对特定
    文章目录1、logistics-param-wrap.wxml2、logistics-param-wrap.js3、logistics-param-wrap.wxss1、logistics-param-wrap.wxml<viewclass="logistics-param-wrap"><viewclass="logistics-param-title">物流参数</view><vi......