线性动态规划专讲

简介: 线性动态规划专讲

线性规划概念

动态规划的主要特点是状态的推导是按照问题规模 i ii 从小到大依次推过去的(或者从后往前一直推过来的,比如「石子游戏」、「2140.解决智力问题」就是从后往前推的),较大规模的问题的解依赖较小规模的问题的解。

通常做此类问题步骤如下:

image.png

LeetCode 877. 石子游戏

class Solution {
    public boolean stoneGame(int[] piles) {
        int n = piles.length;
        long[][] dp = new long[n + 1][n + 1];
        // dp[i][j]代表从区间[i,j]之间获得的最多分数
        // dp[i][j] = Math.max(piles[i] + dp[i + 1][j], dp[i][j - 1] + plies[j])
        // dp[i][i] = 0
        // dp[0][n - 1] > 0 ? true : false;
        for (int i = 0 ; i < n; i++) {
            dp[i][i] = 0;
        }
        for (int i = n - 1; i >= 0; i--) {
            for (int j = i + 1; j < n; j++) {
                dp[i][j] = Math.max(piles[i] + dp[i + 1][j], dp[i][j - 1] + piles[j]);
            }
        }
        return dp[0][n - 1] > 0 ? true : false;
    }
}

LeetCode 2140. 解决智力问题

class Solution {
    public long mostPoints(int[][] q) { 
        int n = q.length;
        // dp[i]的含义是从下标i~n-1获取的最大分数值
        // dp[i] = Math.max(dp[Math.min(n, q[i][1])] + q[i][0], dp[i])
        long[] dp = new long[n + 1];
        for (int i = n - 1; i >= 0; i--) {
            dp[i] = Math.max(dp[Math.min(n, i + q[i][1] + 1)] + q[i][0], dp[i + 1]);
        }
        return dp[0];
    }
}

LeetCode 72. 编辑距离

class Solution {
    public int minDistance(String word1, String word2) {
        int n = word1.length();
        int m = word2.length();
        // 含义:dp[i][j]代表Word1从下标0~i和word2从下标0~j所使用的的最少操作次数
        // 状态转移方程:dp[i][j] = Math.min(dp[i  -1][j] + 1,Math.min(dp[i][j - 1] + 1, dp[i - 1][j - 1] + (word1.charAt(i - 1) != word2.charAt(j - 1) ? 1 : 0)));
        int[][] dp = new int[n + 1][m + 1];
        if (n * m == 0) {
            return n + m;
        }
        for (int i = 0; i <= n; i++) {
            dp[i][0] = i;
        }
        for (int j = 0 ; j <= m ; j++) {
            dp[0][j] = j;
        }
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                int left = dp[i  -1][j] + 1;
                int down = dp[i][j - 1] + 1;
                int left_down = dp[i - 1][j - 1];
                if (word1.charAt(i - 1) != word2.charAt(j - 1)) {
                    left_down++;
                }
                dp[i][j] = Math.min(left_down, Math.min(left, down));
            }
        }
        return dp[n][m];
    }
}


目录
打赏
0
0
0
0
23
分享
相关文章
[大厂实践] 无停机迁移大规模关键流量 (下)
[大厂实践] 无停机迁移大规模关键流量 (下)
138 0
【Redis】哨兵(Sentinel)原理与实战全解~炒鸡简单啊
Redis 的哨兵模式(Sentinel)是一种用于实现高可用性的机制。它通过监控主节点和从节点,并在主节点故障时自动进行切换,确保集群持续提供服务。哨兵模式包括主节点、从节点和哨兵实例,具备监控、通知、自动故障转移等功能,能显著提高系统的稳定性和可靠性。本文详细介绍了哨兵模式的组成、功能、工作机制以及其优势和局限性,并提供了单实例的安装和配置步骤,包括系统优化、安装、配置、启停管理和性能监控等。此外,还介绍了如何配置主从复制和哨兵,确保在故障时能够自动切换并恢复服务。
Vue引入Echarts图表的使用
Vue引入Echarts图表的使用
120 0
运营分析利器——SLS窗口漏斗分析
漏斗分析当下已被广泛应用于产品运营分析过程中,成为用户增长、客户流失、留存转化等的重要分析方法。 常见的漏斗分析过程如下图所示,当产品或者运营活动发布后, 通过收集运营数据、并建立漏斗模型,然后根据漏斗模型进行统计和分析,定位问题,从而进行对应的优化迭代,并持续跟踪,最终实现用户增长、产品优化等目标...
206 0
运营分析利器——SLS窗口漏斗分析
MSE服务治理最佳实践:基于Ingress-nginx网关实现全链路灰度
微服务架构下,有一些需求开发涉及到微服务调用链路上的多个微服务同时改动。通常每个微服务都会有灰度环境或分组来接受灰度流量。我们希望进入上游灰度环境的流量也能进入下游灰度的环境中,确保1个请求始终在灰度环境中传递。即使这个调用链路上有一些微服务应用不存在灰度环境,那么这些微服务应用在请求下游应用的时候依然能够回到下游应用的灰度环境中。我们通过 MSE 提供的全链路灰度能力,可以在不需要修改任何业务代码的情况下,轻松实现上述所说的全链路灰度能力。
MSE服务治理最佳实践:基于Ingress-nginx网关实现全链路灰度
统一观测丨如何使用Prometheus 实现性能压测指标可观测
简介:本篇阐述如何使用 Prometheus 实现性能压测 Metrics 的可观测性。
295 0
P1421 小玉买文具
P1421 小玉买文具
169 0
C语言输入字符串
说明:str 为字符串的起始地址,size 为字符数组的尺寸。函数读取用户从键盘输入的字符串(以换行符 ‘\n’ 结束)到 str 所指示的字符数组中,并在字符末尾添加字符串结束标记 ‘\0’,函数值为 str。显然,字符串的最大长度为 size - 1,为字符串结束标记 ‘\0’ 预留空间。若用户输入的字符过多,则函数最多读取 size - 1 个字符,剩余字符仍留在缓冲区中,可以继续被后面的输入函数读取。我们综合两者的优点,克服两者的缺点,设计一个函数来输入字符串。
202 0

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等