力扣刷题题解注意(8

力扣746使用最小花费爬楼梯

首先这道题目的理解需要花费一点时间,比如说给定n=cost.size()个台阶,那么数组下标的序号是0~n-1,如果第0层是最底层的话那么第n层是最顶层,题目问的是到达最顶层也就是第n层需要的花费。因为到达每一层需要的花费都是由上一层决定的,所以本题属于dp题目。对于递归函数的dp数组定义可以想到两种情况(1)dp[i]表示到达第i层需要的最小花费是多少(2)dp[i]表示到达第i层的顶层需要的最小花费是多少。对于不同的dp含义对应不同的递归公式,也对应不同的初始化,总体来说(1)比较好理解。考虑这种问题的时候注重想清楚如何逐步向后递归,而不是思考在离顶层还有几步的时候停下,因为这个已经包含在逐步向后递归的过程了。

int minCostClimbingStairs(vector<int>& cost) {
        int n=cost.size();
        vector<int>dp(n+1);//到达楼梯第i层需要的花费
        dp[0]=0;//从0 huo 1出发都可以,所以出发即到达,所以花费为0
        dp[1]=0;
        for(int i=2;i<=n;++i)
        {
            dp[i]=min(dp[i-1]+cost[i-1],dp[i-2]+cost[i-2]);//可以前面一级台阶到也可以前面两级
        }
        return dp[n];
    }

力扣62不同路径

积累:定义m行n列个vector二维数组:

vector<vector<int>>dp(m,vector<int>(n));//m行n列的二维数组

力扣63不同路径II

记得考虑第一个位置是障碍物的情况,此时所有位置到达的路径是0

if(obstacleGrid[0][0]==1)//只有一个位置但是有障碍物
  return 0;

力扣416分割等和子集

1.看到这道题目将子集分割,首先想到的解法是双指针。但是这道题目不能使用双指针元素和,因为双指针移动的前提是数组有序,但是问题并不是基于要保证数组一定有序,比如说1 1 2 2 ,如果数组有序,那么返回值是false,但实际上1+2=1+2,无法使用双指针结束

2.当觉得使用双指针无法解决的时候,向背包解法靠近。每一个元素只能用一次所以是01背包,但是究竟递推公式是什么,也就是我们要找到一种什么关系? 首先可以确定的是dp[i]的含义是容量为i的时候一共有和为dp[i]的元素和,那肯定不是所有的最大容量i都会将背包装满,也就是dp[i]=i,所以我们要找的是dp[i]==i时的数组,如果无法相等也就是说当i=sum/2时,无法将这个背包装满,无法得到元素和的一半。

这道题的难点不在于想到是DP问题,也不在于如何定义dp数组,在于如何将dp数组转化为我们需要解决的问题,也就是对于 i 和 dp[i]之间关系的探索。

bool canPartition(vector<int>& nums) {
        //首先这道题目不能使用双指针元素和,因为双指针移动的前提是数组有序,但是问题并不是基于要保证数组一定有序,比如说1 1 2 2 ,如果数组有序本题就不成立
        int total=accumulate(nums.begin(),nums.end(),0);
        if(total%2==1)return false;//无法找到两个相等的子集
        int sum=total/2;
        vector<int>dp(10001,0);//定义在第0-i个数据里面找和为dp[i]
        //如果背包问题是最大还是最小和
        for(int i=0;i<nums.size();++i)
        {
            for(int j=sum;j>=nums[i];--j)
            {
                dp[j]=max(dp[j],dp[j-nums[i]]+nums[i]);//容量为i时最多能容纳重量为i
            }
        }
        if(dp[sum]==sum)return true;//容量为sum的背包正好能装下和为sum的数字
        return false;
    }

 

  • 11
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值