【动态规划】简单多状态dp问题:按摩师,打家劫舍,删除并获得点数,粉刷房子,买卖股票的最佳时机

文章目录

1. 按摩师 (面试题17.16)

按摩师

题目描述

解题思路

  • 状态表示:到第i个元素累计最长时间为dp[i]。对于每个元素都可以选择接受或不接受。需要两个数组来表示:f[i]表示接受当前预约的最长时间,g[i]表示不接受当前预约的最长时间
  • 状态转移方程:
    • 如果接受i预约,前一个一定不接受。f[i] = g[i-1] + nums[i]
    • 如果不接受,前一个预约可能接受,也可能不接受。取最大值。 g[i] = max(f[i-1],g[i-1])
  • 初始化:如果第一预约接受,f[0] = nums[0];不接受则g[i] =0

代码实现

java 复制代码
class Solution {
    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(f[i-1],g[i-1]);
        }
        return Math.max(f[n-1],g[n-1]);
    }
}

2. 打家劫舍II(LC 213)

打家劫舍II

题目描述

解题思路

分类讨论,把环形问题转换为线性问题。

  • 如果偷0号位置,则1号和n-号不可以偷,2号到n-2号可以偷,变成了上一题的解法
  • 如果不偷0号位置,则1号到n-号可以偷。

代码实现

java 复制代码
class Solution {
    int[] nums;
    public int rob(int[] _nums) {
        nums = _nums;
        int n = nums.length;

        int case1 = rob1(2,n-2,n) + nums[0];
        int case2 = rob1(1,n-1,n);
        return Math.max(case1,case2);
    }

    int rob1(int l,int r,int n){
        if(l>r)
            return 0;

        int[] f = new int[n];
        int[] g = new int[n];
        f[l] = nums[l];

        for(int i = l;i<=r;i++){
            f[i] = g[i-1]+nums[i];
            g[i] = Math.max(f[i-1],g[i-1]);
        }
        return Math.max(f[r],g[r]);
    }
}

3. 删除并获得点数(LC 740)

删除并获得点数

题目描述

解题思路

用数组hash记录每个数字出现的次数。这样就转换为第一个题,用两个数组表示当前数字删或不删得到的总和。

代码实现

java 复制代码
class Solution {
    public int deleteAndEarn(int[] nums) {
        int[] hash = new int[10001];
        int max = 0;
        for(int num:nums){
            hash[num]++;
            max = Math.max(max,num);
        }

        int[] f = new int[max+1];
        int[] g = new int[max+1];

        g[1] = hash[1];

        for(int i = 2;i<=max;i++){
            f[i] =  Math.max(g[i-1],f[i-1]);
            g[i] =f[i-1] + hash[i]*i;
        }
        return Math.max(f[max],g[max]);
    }
}

4. 粉刷房子(LCR091)

粉刷房子

题目描述

解题思路

与第一题类似,只需要用三个数组做动态规划即可

代码实现

java 复制代码
class Solution {
    public int minCost(int[][] costs) {
        int n = costs.length;
        int[] red = new int[n];
        int[] blue = new int[n];
        int[] green = new int[n];
        red[0] = costs[0][0];
        blue[0] = costs[0][1];
        green[0] = costs[0][2];

        for(int i =1;i<n;i++){
            red[i] = Math.min(green[i-1],blue[i-1])+costs[i][0];
            blue[i] = Math.min(green[i-1],red[i-1])+costs[i][1];
            green[i] = Math.min(red[i-1],blue[i-1])+costs[i][2];
        }
        return Math.min(green[n-1],Math.min(red[n-1],blue[n-1]));
    }
}
相关推荐
KAU的云实验台2 小时前
单/多UAV、静/动态路径规划,基于PlatEMO平台的带约束多目标优化 本文核心内容:
算法·matlab·无人机
Liangwei Lin2 小时前
洛谷 P1807 最长路
数据结构·算法
会编程的土豆3 小时前
【数据结构与算法】二叉树从建立开始
数据结构·c++·算法
_日拱一卒3 小时前
LeetCode:最大子数组和
数据结构·算法·leetcode
计算机安禾3 小时前
【数据结构与算法】第22篇:线索二叉树(Threaded Binary Tree)
c语言·开发语言·数据结构·学习·算法·链表·visual studio code
算法鑫探3 小时前
解密2025数字密码:数位统计之谜
c语言·数据结构·算法·新人首发
计算机安禾3 小时前
【数据结构与算法】第21篇:二叉树遍历的经典问题:由遍历序列重构二叉树
c语言·数据结构·学习·算法·重构·visual studio code·visual studio
信奥胡老师4 小时前
P1255 数楼梯
开发语言·数据结构·c++·学习·算法
爱睡懒觉的焦糖玛奇朵5 小时前
【工业级落地算法之人员摔倒检测算法详解】
人工智能·python·深度学习·神经网络·算法·yolo·目标检测