疯狂DP(动态规划)

  第一个小目标:50道动态规划题目。

  使用prev进行返回可能存在越界风险。使用cur进行返回需要在程序最开始时判断条件并返回。

1. 509 斐波那契数

  本题的核心在于两个变量(prev和cur)逐步往前走。

class Solution {
    
    
public:
    int fib(int n) {
    
    
        int prev = 0, cur = 1;

        while (n--) {
    
    
            int temp = cur;
            cur = cur + prev;
            prev = temp;
        }

        return prev;
    }
};

在这里插入图片描述

class Solution {
    
    
public:
    int fib(int n) {
    
    
        if (n <= 1) return n;

        int prev = 0, cur = 1;
        n -= 1;
        while (n--) {
    
    
            int temp = cur;
            cur = cur + prev;
            prev = temp;
        }


        return cur;

    }
};

在这里插入图片描述

2. 1137 第 N 个泰波那契数

  需要注意的是用哪个变量作为返回值,其中该变量的范围很重要,比如返回值的最大值为 2 31 − 1 2^{31}-1 2311,如果使用prev作为返回,则cur和prev使用int则会产生越界现象。

class Solution {
    
    
public:
    int tribonacci(int n) {
    
    
        unsigned int prev = 0, cur = 1, nex = 1;

        while (n--) {
    
    
            unsigned int t1 = cur;
            unsigned int t2 = nex;
            nex = prev + cur + nex;
            prev = t1;
            cur = t2;
        }

        return prev;
    }
};
class Solution {
    
    
public:
    int tribonacci(int n) {
    
    
        if (n <= 1) return n;

        int prev = 0, cur = 1, nex = 1;
        n -= 2;
        while (n--) {
    
    
            int t1 = cur;
            int t2 = nex;
            nex += cur + prev;
            cur = t2;
            prev = t1;
        }


        return nex;

    }
};

3. 70 爬楼梯

class Solution {
    
    
public:
    int climbStairs(int n) {
    
    
        if (n == 1) return 1;
        int prev = 1, cur = 2;

        n -= 2;

        while (n--) {
    
    
            int temp = cur;
            cur += prev;
            prev = temp;
        }

        return cur;
    }
};

  确定零点很重要,这里的零点是2。

4. 746 使用最小花费爬楼梯

class Solution {
    
    
public:
    int minCostClimbingStairs(vector<int>& cost) {
    
    
        if (cost.size() == 2) return min(cost[0], cost[1]);

        cost.push_back(0);
        int prev = cost[0];
        int cur = cost[1];

        for (int i=2; i<cost.size(); ++i) {
    
    
            int temp = cur;
            cur = min(prev, cur) + cost[i];
            prev = temp;

        }

        cost.pop_back();
        return cur;
    }
};

 爬楼梯和打家劫舍有很大的区别。前者和后者的区别之处在于:

5. 198 打家劫舍

f(0) = nums[0]
f(1) = max(f(0), f(1))

f(i) = max(f(i-1), f(i-2)+nums[i])

class Solution {
    
    
public:
    int rob(vector<int>& nums) {
    
    
        if (nums.size() == 1) return nums[0];

        int prev = nums[0]; 
        int cur = max(nums[0], nums[1]);

        for (int i=2; i<nums.size(); ++i) {
    
    
            int temp = cur;
            cur = max(prev+nums[i], cur);
            prev = temp;
        }

        return cur;
    }
};

  不能取相邻,本来原本是两个方向,为什么用单个方向来代替也是可以的~~~

おすすめ

転載: blog.csdn.net/weixin_47532216/article/details/121394425