算法奇妙屋(十四)-简单多状态dp问题

文章目录

一. 力扣面试题 17.16. 按摩师

1. 题目

这里题目的意思是这一组数据, 不能选择相邻的数字, 最少间隔一个, 然后求选择数据和的最大值

2. 算法原理

3. 代码

java 复制代码
    public int massage(int[] nums) {
        int n = nums.length;
        if (n == 0) {
            return 0;
        }
        int[] f = new int[n];
        int[] g = new int[n];
        f[0] = nums[0];
        for (int i = 1; i < n; i++) {
            f[i] = g[i- 1] + nums[i];
            g[i] = Math.max(g[i - 1], f[i - 1]);
        }
        return Math.max(f[n - 1], g[n - 1]);
    }

二. 力扣LCR 090. 打家劫舍 II

1. 题目

相比于打家劫舍I(上一道题和打家劫舍I解法一样), 这里的房子只是变为了环形

2. 算法原理

3. 代码

java 复制代码
    public int rob(int[] nums) {
        int n = nums.length;
        // 0 偷
        int t1 = robI(nums, 2, n - 2) + nums[0];
        // 0 不偷
        int t2 = robI(nums, 1, n - 1);
        return Math.max(t1, t2);
    }

    public int robI(int[] nums, int start, int end) {
        if (start > end) {
            return 0;
        }
        int n = nums.length;
        int[] f = new int[n];
        int[] g = new int[n];
        f[start] = nums[start];
        for (int i = start + 1; i <= end; i++) {
            f[i] = g[i - 1] + nums[i];
            g[i] = Math.max(f[i - 1], g[i - 1]);
        }
        return Math.max(f[end], g[end]);
    }

三. 力扣740. 删除并获得点数

1. 题目

2. 算法原理

3. 代码

java 复制代码
    public int deleteAndEarn(int[] nums) {
        int[] rob = new int[10001];
        int max = 0;
        for (int x : nums) {
            if (x > max) {
                max = x;
            }
            rob[x] += x;
        }
        int[] f = new int[max + 1];
        int[] g = new int[max + 1];
        f[0] = rob[0];
        for (int i = 1; i <= max; i++) {
            f[i] = g[i - 1] + rob[i];
            g[i] = Math.max(f[i - 1], g[i - 1]);
        }
        return Math.max(f[max], g[max]);
    }  

四. 力扣LCR 091. 粉刷房子

1. 题目

2. 算法原理

3. 代码

java 复制代码
    public int minCost(int[][] costs) {
        int n = costs.length;
        int[] r = new int[n + 1];
        int[] b = new int[n + 1];
        int[] g = new int[n + 1]; 
        for (int i = 1; i <= n; i++) {
            r[i] = Math.min(b[i - 1], g[i - 1]) + costs[i - 1][0];
            b[i] = Math.min(r[i - 1], g[i - 1]) + costs[i - 1][1];
            g[i] = Math.min(b[i - 1], r[i - 1]) + costs[i - 1][2];
        }
        return Math.min(r[n],Math.min(b[n], g[n]));
    }

五. 力扣309. 买卖股票的最佳时机含冷冻期

1. 题目

2. 算法原理

小编参悟这道题也是参悟了2个小时,才弄懂, 只能第一次见到题解的时候云里雾里, 后来多想了想, 才弄明白一些隐含条件, 一些注意事项都写到了下面图解里

3. 代码

java 复制代码
    public int maxProfit(int[] prices) {
        int n = prices.length;
        int[][] dp = new int[n][3];
        dp[0][0] = -prices[0];
        for (int i = 1; i < n; i++) {
            dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][2] - prices[i]);
            dp[i][1] = dp[i - 1][0] + prices[i];
            dp[i][2] = Math.max(dp[i - 1][1], dp[i - 1][2]);
        }
        return Math.max(dp[n - 1][1], dp[n - 1][2]);
    }

六. 力扣714. 买卖股票的最佳时机含手续费

1. 题目

2. 算法原理

3. 代码

java 复制代码
    public int maxProfit(int[] prices, int fee) {
        int n = prices.length;
        int[] f = new int[n];
        int[] g = new int[n];
        f[0] = -prices[0];
        for (int i = 1; i < n; i++) {
            f[i] = Math.max(f[i - 1], g[i - 1] - prices[i]);
            g[i] = Math.max(f[i - 1] + prices[i] - fee, g[i - 1]);
        }
        return g[n - 1];
    }

七. 力扣123. 买卖股票的最佳时机 III

1. 题目

2. 算法原理

3. 代码

java 复制代码
    public int maxProfit(int[] prices) {
        int n = prices.length;
        int[][] f = new int[n][3];
        int[][] g = new int[n][3];
        f[0][0] = -prices[0];
        f[0][1] = f[0][2] = g[0][1] = g[0][2] = -0x3f3f3f3f;
        for (int i = 1; i < n; i++) {
            for (int j = 0; j < 3; j++) {
                f[i][j] = Math.max(f[i - 1][j], g[i - 1][j] - prices[i]);
                g[i][j] = g[i - 1][j];
                if (j - 1 >= 0) {
                    g[i][j] = Math.max(g[i][j], f[i - 1][j - 1] + prices[i]);
                }
            }
        }
        return Math.max(g[n - 1][0], Math.max(g[n - 1][1], g[n - 1][2]));
    }

八. 力扣188. 买卖股票的最佳时机 IV

1. 题目

相较于上一道题,这里的最大交易两次变为了k次, 但是丝毫不慌, 因为我们上一道题提供的解法是通用的, 不管你最大限制交易多少次, 都是一样的解法

2. 算法原理

因为我们上一道题的解法和这道题一模一样, 这里我就懒一下,不过多赘述, 直接从上面讲解法复制下来了, 同样也是方便大家观看

3. 代码

java 复制代码
    public int maxProfit(int k, int[] prices) {
        int n = prices.length;
        int[][] f = new int[n][k + 1];
        int[][] g = new int[n][k + 1];
        for (int j = 1; j <= k; j++) {
            f[0][j] = g[0][j] = -0x3f3f3f3f;
        }
        f[0][0] = -prices[0];
        for (int i = 1; i < n; i++) {
            for (int j = 0; j <= k; j++) {
                f[i][j] = Math.max(f[i - 1][j], g[i - 1][j] - prices[i]);
                if (j - 1 >= 0) {
                    g[i][j] = Math.max(g[i - 1][j], f[i - 1][j - 1] + prices[i]);
                }else {
                    g[i][j] = g[i - 1][j];
                }
            }
        }
        int max = 0;
        for (int j = 0; j <= k; j++) {
            if (g[n - 1][j] > max) {
                max = g[n - 1][j];
            }
        }
        return max;
    }
相关推荐
刀法如飞2 分钟前
Java数组去重的20种实现方式——指导AI解决不同问题的思路
java·算法·面试
良木生香7 分钟前
【C++初阶】STL——Vector从入门到应用完全指南(1)
开发语言·c++·神经网络·算法·计算机视觉·自然语言处理·数据挖掘
Brilliantwxx7 分钟前
【C++】String的模拟实现(代码实现与坑点讲解)
开发语言·c++·笔记·算法
憨波个17 分钟前
【说话人日志】DOVER:diarization 输出融合算法
人工智能·算法·音频·语音识别·聚类
爱学习的张大19 分钟前
具身智能论文问答(四):pi0
人工智能·算法
上弦月-编程24 分钟前
指针编程:高效内存管理核心
java·数据结构·算法
罗超驿25 分钟前
双指针算法经典案例:LeetCode 283. 移动零(Java详解)
java·算法·leetcode
人道领域32 分钟前
【数据结构与算法分析】二叉树面试通关手册:遍历图解 · 分类对比 · 代码模板
数据结构·算法·leetcode·深度优先
水蓝烟雨34 分钟前
2901. 最长相邻不相等子序列 II
算法·leetcode
郝学胜-神的一滴37 分钟前
二分类任务核心:BCE 损失函数从原理到 PyTorch 实战
人工智能·pytorch·python·算法·机器学习·分类·数据挖掘