leetcode 动态规划入门问题细化解析(一)

1.最小花费爬楼梯
https://leetcode-cn.com/problems/min-cost-climbing-stairs/

大佬的题解,跟官方解答思路一样(自己加了注释内容)

class Solution {
public:
    int minCostClimbingStairs(vector<int>& cost) {
        int c1 = cost[0];
        int c2 = cost[1];
        int N = cost.size();
        for (int i = 2; i < N; ++i) {
            int c3 = min(c1, c2) + cost[i]; 
            //从i = 2开始,本层的体力加上min(到达第i - 2层花费体力的最小值,到达第i - 1层花费体力的最小值)
            c1 = c2; 
            //c1为到达第i - 1层花费体力的最小值
            c2 = c3; 
            //c2为到达第i层花费体力的最小值
        }
        return min(c1, c2);
         //比较到N - 1和N - 2花费体力的值
    }
};

作者:da-li-wang
链接:https://leetcode-cn.com/problems/min-cost-climbing-stairs/solution/c-dong-tai-gui-hua-ti-jie-by-da-li-wang-3/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

这个大佬的题解更好理解

class Solution{
	public:
		int minCostClimbingStairs(vector<int>& cost) {
			int num=cost.size();
			for(int i=2;i<num;++i)cost[i]+=min(cost[i-1],cost[i-2]);
			return min(cost[num-1],cost[num-2]);
	    }
}; 

作者:yzwz
链接:https://leetcode-cn.com/problems/min-cost-climbing-stairs/solution/xiang-dang-yu-yi-ge-fei-bo-na-qi-shu-lie-by-yzwz/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

2.打家劫舍
https://leetcode-cn.com/problems/house-robber/
具体分析看题解第二位大佬(灵魂画手)的题解

思路
标签:动态规划
动态规划方程:dp[n] = MAX( dp[n-1], dp[n-2] + num )
由于不可以在相邻的房屋闯入,所以在当前位置 n 房屋可盗窃的最大值,要么就是 n-1 房屋可盗窃的最大值,要么就是 n-2 房屋可盗窃的最大值加上当前房屋的值,二者之间取最大值
举例来说:1 号房间可盗窃最大值为 33 即为 dp[1]=3,2 号房间可盗窃最大值为 44 即为 dp[2]=4,3 号房间自身的值为 22 即为 num=2,那么 dp[3] = MAX( dp[2], dp[1] + num ) = MAX(4, 3+2) = 5,3 号房间可盗窃最大值为 55
时间复杂度:O(n)O(n),nn 为数组长度

class Solution {
    public int rob(int[] nums) {
        int len = nums.length;
        if(len == 0)
            return 0;
        int[] dp = new int[len + 1];
        dp[0] = 0;
        dp[1] = nums[0];
        for(int i = 2; i <= len; i++) {
            dp[i] = Math.max(dp[i-1], dp[i-2] + nums[i-1]);
        }
        return dp[len];
    }
}

作者:guanpengchn
链接:https://leetcode-cn.com/problems/house-robber/solution/hua-jie-suan-fa-198-da-jia-jie-she-by-guanpengchn/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

我用C++写了一个没过

class Solution {
public:
    int rob(vector<int>& nums) {
        int len = nums.size();
        if(len == 0)
            return 0;
        if(len == 1)
            return nums[0];
		//nums[1] = max(nums[0], nums[1]);
        for(int i = 2; i < len; i++){
            nums[i] = max(nums[i] + nums[i - 2], nums[i - 1]);
        }
        return max(nums[len - 1], nums[len - 2]);
    }
};

是因为注释掉的那句没加上,过不了输入:[2,1,1,2] 正确输出:4
所以还是看看大佬的

3.除数博弈
https://leetcode-cn.com/problems/divisor-game/
(没看题解时,自己只想到爱丽丝令N-x为非三素数时她才能赢,若N = kx, x不等于1,则N - x = (k - 1)x = N’,N’不可能是素数)

题解中的第一位大佬的归纳法用自己的话概括一下(语文课套路)
1.爱丽丝占到 2 赢,占到 1 输;
2.若爱丽丝当前为奇数,奇数的约数只能是奇数或者 1,因此下一个一定是偶数;
3.若爱丽丝当前为偶数, 偶数的约数可以是奇数可以是偶数也可以是 1,因此直接减 1,则下一个是奇数,即鲍勃拿到的一定是奇数,爱丽丝拿到的一定是偶数,一直变小就会到2;

因此,奇则输,偶则赢

class Solution:
    def divisorGame(self, N: int) -> bool:
        target = [0 for i in range(N+1)]
        target[1] = 0 #若爱丽丝抽到1,则爱丽丝输
        if N<=1:
            return False
        else:
        
            target[2] = 1 #若爱丽丝抽到2,则爱丽丝赢
            for i in range(3,N+1):
                for j in range(1,i//2): #没学过爬虫,意思应该是从1到i的根号(?),j代表x
                    # 若j是i的余数且target[i-j]为假(0)的话,则代表当前为真(1)
                    if i%j==0 and target[i-j]==0: #鲍勃拿到i - j,而target[i - j] = 0代表失败,鲍勃失败爱丽丝的target[i] = 1
                        target[i] = 1
                        break
            return target[N]==1

作者:pandawakaka
链接:https://leetcode-cn.com/problems/divisor-game/solution/python3gui-na-fa-by-pandawakaka/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

4.判断子序列
https://leetcode-cn.com/problems/is-subsequence/
这是博第一个写出来的在动态规划下的题目,虽然不是用动态规划的方法~

class Solution {
public:
    bool isSubsequence(string s, string t) {
        int len1 = s.length();
        long long len2 = t.length();
        long long ma = len2;
        for(int i = len1 - 1; i >= 0; i--){
            bool f = false;
            for(int j = ma - 1; j >= 0; j--){
                if(s[i] == t[j]){
                    ma = j;
                    f = true;
                    break;
                }  
            }
            if(f == false){
                return false;
            }
        }
        return true;
    }
};
发布了4 篇原创文章 · 获赞 0 · 访问量 42

猜你喜欢

转载自blog.csdn.net/weixin_44284194/article/details/104234772