dp

斐波那契

class Solution {
public:
    int fib(int N) {
        if (N <= 1) return N;
        vector<int> dp(N + 1);//创建一个n+1大小的数组()vector<int> dp(n);表示创建大小为n的数组, vector<vector<int>> dp(row, vector<int>(col));表示创建row行 col列的二维数组
        dp[0] = 0;
        dp[1] = 1;
        for (int i = 2; i <= N; i++) {
            dp[i] = dp[i - 1] + dp[i - 2];
        }
        return dp[N];
    }
};

上面的优化 只用两个位置

class Solution {
public:
    int fib(int N) {
        if (N <= 1) return N;
        int dp[2];
        dp[0] = 0;
        dp[1] = 1;
        for (int i = 2; i <= N; i++) {
            int sum = dp[0] + dp[1];//
            dp[0] = dp[1];第一个位置放上一次的答案
            dp[1] = sum;//第二个位置始终放答案
        }
        return dp[1];
    }
};

爬楼梯

关于初始话dp[0]是1还是0的讨论?------------------>题目没有说,你管他干什么?

需要注意的是:题目中说了n是一个正整数,题目根本就没说n有为0的情况。

所以本题其实就不应该讨论dp[0]的初始化!

我相信dp[1] = 1,dp[2] = 2,这个初始化大家应该都没有争议的。

所以我的原则是:不考虑dp[0]如果初始化,只初始化dp[1] = 1,dp[2] = 2,然后从i = 3开始递推,这样才符合dp[i]的定义。
class Solution {
public:
    int climbStairs(int n) {
        if (n <= 1) return n; // 因为下面直接对dp[2]操作了,防止空指针
        vector<int> dp(n + 1);
        dp[1] = 1;
        dp[2] = 2;//注意这里的dp[2]陷阱!!如果n=1;那么这里就是越界
        for (int i = 3; i <= n; i++) { // 注意i是从3开始的
            dp[i] = dp[i - 1] + dp[i - 2];
        }
        return dp[n];
    }
};

优化同上

花费体力的爬楼梯

class Solution {
public:
    int minCostClimbingStairs(vector<int>& cost) {//cost[i]是爬上那个i对应的体力值,而不是从这层离开需要的体力值
        vector<int> dp(cost.size());//dp[i]的定义:到达第i个台阶所花费的最少体力为dp[i]到达
        dp[0] = cost[0];//爬到第0层需要花费第0层对应的体力值
        dp[1] = cost[1];
        for (int i = 2; i < cost.size(); i++) {
            dp[i] = min(dp[i - 1], dp[i - 2]) + cost[i];
        }//题目没说最后一步
        // 所以最后一步可以理解为不用花费,所以取倒数第一步,第二步的最少值
        return min(dp[cost.size() - 1], dp[cost.size() - 2]);
    }
};



上一篇:【Python数据分析-5】:Pandas常用操作-二维数据合并concat


下一篇:集合覆盖 顶点覆盖: set cover和vertex cover