【动态规划】简单多状态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]));
    }
}
相关推荐
疯狂打码的少年17 分钟前
【数据结构】二叉树的性质(五大性质+计算)
数据结构·笔记·算法
wabs6661 小时前
关于图论【A*算法 | 卡码网127.骑士的攻击的思考】
数据结构·算法·图论·卡码网·广搜的改进版
CIO_Alliance1 小时前
AI认知系列(3)| 数据、算法、算力、场景四要素协同
人工智能·算法·ipaas·系统集成·企业cio联盟·企业级ai化转型
..Dauntless..2 小时前
手写vector vs std::vector:从功能正确到性能达标
算法
m0_547486663 小时前
《数据结构与算法》全套PPT课件2026(中国海洋大学)
数据结构·算法
旖旎夜光3 小时前
LeetCode 904:水果成篮(滑动窗口) —— 题解
数据结构·c++·算法·leetcode·滑动窗口
怪奇云呼军3 小时前
G.711、Opus 和重采样会拖慢识别吗?闪电智能VoiceAgent 的音频入口怎么选
java·人工智能·python·算法·云计算·音视频
乐观勇敢坚强的老彭4 小时前
C++ 竞赛常用算法模板速查表
开发语言·c++·算法
高洁014 小时前
工信部教考中心证书
人工智能·深度学习·算法·机器学习·知识图谱
我变成萤火虫5 小时前
河南萌新联赛2026第(三)场:郑州轻工业大学
数据结构·c++·算法·贪心算法·stl·深度优先·哈希算法