动态规划学习(二)

动态规划学习(二)

  1. 删除并获得点数–打家劫舍的进阶版
    在这里插入图片描述

https://leetcode-cn.com/problems/delete-and-earn/

class Solution {
    public int deleteAndEarn(int[] nums) {
    //设置一个数量数组sum[],再设置一个价值数组var[]
    //(数量数组为了统计数组中个元素的个数,而价值数组则是 各元素的总价值)
     int[] sum=new int[10001]; int[] var=new int[10001];
    //将nums里的各个数进行统计,放进sum数组里
     for(int i=0;i<nums.length;i++){
         sum[nums[i]]++;
     }
    //求出各个元素的总价值
    for(int i=0;i<10001;i++){
        var[i]=i*sum[i];
    }
    //之后,题目就变成了打家劫舍(取每个值都有了对应的价值,且不能取相邻的)
    //初始化变量
    int[] dp=new int[10001];
    dp[0]=var[0];
    //根据状态方程来赋值
    for(int i=1;i<10001;i++){
        if(i==1) dp[i]=Math.max(dp[0],var[i]);
//要么不取(dp[i-1]),要么取 dp[i-2]+var[i](var[i]为当前数的价值)
        else dp[i]=Math.max(dp[i-1],dp[i-2]+var[i]);
    }
    //返回结果
    return dp[10000];
    }
}

动态规划解决缀值问题

关于这部分,他能更加深入的让我们理解动态规划的使用场景。
什么题能用到动态规划?他的标志是什么?

总结下来:应该是:初始值+这个数的值和数组中的值有联系(可以建立状态转移方程)+求最值

这部分一般都会有一个 左面或者右面的初始值如:[0,1) 或者是
(0,1]。
要时刻记住,动态规划求的一般都是左面或者右面一定范围里的最值。

  1. 买卖股票的最佳时机–求前缀值
    在这里插入图片描述
    https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/submissions/
class Solution {
    //利用动态规划求出某天之内的最小买入话费,再用这些天的每一天来减去对应的话费即使最小值
    public int maxProfit(int[] prices) {
        //初始化
        int res=0;
        int[] dp=new int[prices.length];
        dp[0]=prices[0];
        //利用状态方程求dp数组的值
        for(int i=1;i<prices.length;i++){
            dp[i]=Math.min(dp[i-1],prices[i]);
        }
       //遍历prices数组,求出最大利润
       for(int i=0;i<prices.length;i++){
           int temp=prices[i]-dp[i];
           if(temp>res)res=temp;
       }
       //返回对应的解
       return res;

    }
}
  1. 将每个元素替换为右侧的最大元素–后缀
    在这里插入图片描述
    https://leetcode-cn.com/problems/replace-elements-with-greatest-element-on-right-side/
    自己创建 dp 数组做的
class Solution {
    public int[] replaceElements(int[] arr) {
    //初始化
    int[] dp=new int[arr.length];
    dp[arr.length-1]=-1;
    //利用状态方程求出dp各个元素的值
    for(int i=arr.length-2;i>=0;i--){
       dp[i]=Math.max(dp[i+1],arr[i+1]);
    }
    //返回
    return dp;
    }
}

在原来的数组上直接操作

class Solution {
    //在原数组上动态规划
    public int[] replaceElements(int[] arr) {
    
    //利用状态方程求出dp各个元素的值
    int arrTemp=arr[arr.length-1];
    for(int i=arr.length-1;i>=0;i--){
       
       if(i==arr.length-1) arr[arr.length-1]=-1;

       else {
           int temp=arr[i];
           arr[i]=Math.max(arr[i+1],arrTemp);
           arrTemp=temp;
           
       }
    }
    //返回
    return arr;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值