dp算法篇Day4

dp算法篇Day4_第1张图片

"我把每一天都当做新开始,新革命。"


        

16、买卖股票的最佳时机含手续费

(1) 题目分析

dp算法篇Day4_第2张图片 

        完成一笔交易才算达成交易。但其实你可以将手续费加在任意一处上。 

(2) 算法原理dp算法篇Day4_第3张图片

class Solution {
public:
    int maxProfit(vector& prices, int fee) {
        int n = prices.size();

        vector f(n);
        auto g = f;

        f[0] = -prices[0];
        g[0] = 0;

        for(int i=1; i

        


17、买卖股票的最佳时机Ⅲ

(1) 题目解析dp算法篇Day4_第4张图片

 

(2) 算法原理

  dp算法篇Day4_第5张图片

        注: 如果仅仅考虑填无穷的话,如果是一个有符号的整型,减去一个负数,会变成一个无比大的正数,会影响dp表的取值。因此我们这里定义一个 MIN_INT:0x3f3f3f 这是一个通常用来作为"最大值或最小值"的数,因为它不管怎么加减,都不会溢出,出现未定义行为。

class Solution {
public:
    int maxProfit(vector& prices) {
        int n = prices.size();
        const int MIN_INT = -0x3f3f3f3f;

        vector> f(n,vector(3,MIN_INT));
        auto g = f;
        // 初始化
        f[0][0] = -prices[0];
        g[0][0] = 0;

        for(int i=1; i= 1)
                    g[i][j] = max(g[i-1][j],f[i-1][j-1]+prices[i]);
            }
        }
        
        // 查询最大值
        int ret = 0;
        for(int i=0; i<3; ++i){
            ret = max(ret,g[n-1][i]);
        }
    
        return ret;
    }
};


18、买卖股票的最佳时机Ⅳ 

(1) 题目解析

dp算法篇Day4_第6张图片

         如果你对上面 进行 "至多两笔交易" 特别熟悉,也弄懂了状态表达 和 状态方程式,那么这解这道题的代码,甚至可以说 "原封不动" copy一份即可。

(2) 算法原理

dp算法篇Day4_第7张图片

         这里就省略省略, 因为前面的一道题费了很多口舌。只是值得注意,虽然说的是至多k次交易,但是有k+1种情况。

class Solution {
public:
    int maxProfit(int k, vector& prices) {
        int n = prices.size();
        const int MIN_INT = -0x3f3f3f3f;

        vector> f(n,vector(k+1,MIN_INT));
        auto g=f;
        f[0][0] = -prices[0];
        g[0][0] = 0;

        for(int i=1; i=1)
                    g[i][j] = max(g[i-1][j],f[i-1][j-1] + prices[i]);
            }
        }
        int ret = 0;
        for(int i=0; i<=k;++i){
            ret = max(ret,g[n-1][i]);
        }

        return ret;
    }
};


19、最大数组和

(1) 题目解析

dp算法篇Day4_第8张图片

 

(2) 算法原理

dp算法篇Day4_第9张图片

        针对这种子序数组问题,一定要将问题划分为 长度为1 或者 长度>1,每个长度的子序数组都可能成为dp[i-1]的答案一种。 

class Solution {
public:
    int maxSubArray(vector& nums) {
        int n = nums.size();
        
        vector dp(n+1);
        
        int maxVal = INT_MIN;
        for(int i=1; i<=n; ++i){
            dp[i] = max(nums[i-1],dp[i-1]+nums[i-1]);
            maxVal = max(maxVal,dp[i]);
        }

        return maxVal;
    }
};

       


20、环形数组的最大和

(1) 题目解析

dp算法篇Day4_第10张图片

 

(2) 算法原理

dp算法篇Day4_第11张图片

class Solution {
public:
    int maxSubarraySumCircular(vector& nums) {
        int n = nums.size();

        vector f(n+1);
        auto g = f;

        int sum = 0;
        int max_fn = INT_MIN;
        int min_gn = INT_MAX;
        for(int i=1; i<=n; ++i)
        {
            f[i] = max(nums[i-1],f[i-1]+nums[i-1]);
            max_fn = max(max_fn,f[i]);

            g[i] = min(nums[i-1],g[i-1]+nums[i-1]);
            min_gn = min(min_gn,g[i]);
            sum += nums[i-1];
        }

        int max_gn = sum - min_gn;
        // sum == min_gn?
        return max_gn == 0 ? max_fn : max(max_fn,max_gn);
    }
};


本篇到此结束,感谢你的阅读。

祝你好运,向阳而生~

dp算法篇Day4_第12张图片

 

你可能感兴趣的:(dp动规算法,数学建模)