【动态规划】简单多状态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]));
    }
}
相关推荐
手写码匠16 分钟前
从零实现 Prompt 工程引擎:结构化提示、自动优化与多轮自省体系
人工智能·深度学习·算法·aigc
无限码力39 分钟前
阿里算法岗 0530笔试真题 - 多约束条件下的元素匹配统计
算法·阿里笔试真题·阿里机试真题·阿里算法岗笔试
lqqjuly1 小时前
MLA — 多头潜在注意力深度解析
深度学习·神经网络·算法
吴可可1231 小时前
SolidWorks草图转三维DWG技巧
算法
redaijufeng2 小时前
C++雾中风景7:闭包
c++·算法·风景
小欣加油2 小时前
leetcode287寻找重复数
数据结构·c++·算法·leetcode
尽兴-3 小时前
2.1 向量基础:Embedding、余弦相似度、欧氏距离、向量检索
算法·embedding·欧氏距离·向量检索·余弦相似度
Black蜡笔小新3 小时前
自动化AI算法训练服务器DLTM训推一体工作站赋能多行业智能化升级
人工智能·算法·自动化
怪兽学LLM3 小时前
LeetCode 438 找到字符串中所有字母异位词(Python 固定滑动窗口+字符计数解法)
python·算法·leetcode
满怀冰雪3 小时前
第04篇-双指针算法-从有序数组到回文判断的高频解法
java·算法