刷爆leetcode Day9 DP

16. 买卖股票的最佳时期含手续费(medium)

https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/submissions/575767896/

class Solution {
public:
    int maxProfit(vector<int>& prices, int fee) {
      //分为两种情况
      //当天结束手上有股票(前天有股票今天什么都不做或者前天没股票今天购买股票)
      //当天结束手上没股票(前天有股票今天卖出股票得到利润支出手续费或者昨天手上没股票今天什么都不做)
      int n=prices.size();
      vector<int>fdp(n);
      vector<int>gdp(n);
      fdp[0]=-prices[0];
      for(int i=1;i<n;i++)
      {
        fdp[i]=max(fdp[i-1],gdp[i-1]-prices[i]);
        gdp[i]=max(fdp[i-1]+prices[i]-fee,gdp[i-1]);
      }
      return gdp[n-1];
    }
};

17. 买卖股票的最佳时机III(hard)

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        //分为两种情况
        //当天结束手上有股票(前天有股票今天什么都不做或者前天没股票今天购买股票)
        //当天结束手上没股票(前天有股票今天卖出股票得到利润交易记录加1或者昨天手上没股票今天什么都不做)
        //最多可以完成两笔交易
       int n=prices.size(); 
       vector<vector<int>> fdp(n,vector<int>(3,-0x3f3f3f));
       vector<vector<int>> gdp(n,vector<int>(3,-0x3f3f3f));
       fdp[0][0]=-prices[0];
       gdp[0][0]=0;
       for(int i=1;i<n;i++)
       {
            for(int j=0;j<3;j++)
            {
                fdp[i][j]=max(fdp[i-1][j],gdp[i-1][j]-prices[i]);
                gdp[i][j]=gdp[i-1][j];
                if(j-1>=0)
                gdp[i][j]=max(fdp[i-1][j-1]+prices[i],gdp[i-1][j]);//j-1可能越界,我们特殊处理一下
            }
       }
       return max(gdp[n-1][0],max(gdp[n-1][1],gdp[n-1][2]));
    }
};

18. 买卖股票的最佳时机IV(hard)

https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-iv/submissions/575774292/

class Solution {
public:
    int maxProfit(int k, vector<int>& prices) {
        //分为两种情况
        //当天结束手上有股票(前天有股票今天什么都不做或者前天没股票今天购买股票)
        //当天结束手上没股票(前天有股票今天卖出股票得到利润交易记录加1或者昨天手上没股票今天什么都不做)
        //最多可以完成k%(n/2)笔交易
        //0x3f3f3f,int能表示的最大范围的一半
        int n=prices.size();
        k=min(k,n/2);//0到k天,一共k+1次交易
        vector<vector<int>> fdp(n,vector<int>(k+1,-0x3f3f3f));
        vector<vector<int>> gdp(n,vector<int>(k+1,-0x3f3f3f));
        fdp[0][0]=-prices[0];
        gdp[0][0]=0;
        for(int i=1;i<n;i++)
        {
            for(int j=0;j<k+1;j++) //0到k次
            {
                fdp[i][j]=max(fdp[i-1][j],gdp[i-1][j]-prices[i]);
                gdp[i][j]=gdp[i-1][j];
                if(j-1>=0)
                gdp[i][j]=max(fdp[i-1][j-1]+prices[i],gdp[i-1][j]);
            }
        }
        int ret=-0x3f3f3f;
        for(int l=0;l<k+1;l++)
        ret=max(ret,gdp[n-1][l]);

        return ret;
    }
};

19. 最⼤子数组和(medium)

https://leetcode.cn/problems/maximum-subarray/submissions/575775026/

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
      //dp表i位置表示以该位置为结尾的子数组的最大值
      //子数组分为两种
      //长度等于1
      //长度大于1
      int n=nums.size();
      vector<int> dp(n);
      dp[0]=nums[0];
      int _max=dp[0];
      for(int i=1;i<n;i++)
      {
        dp[i]=max(nums[i],dp[i-1]+nums[i]);
        _max=max(_max,dp[i]);
      }
      return _max;
    }
};

20. 环形子数组的最大和(medium)

https://leetcode.cn/problems/maximum-sum-circular-subarray/submissions/575777133/

class Solution {
public:
    int maxSubarraySumCircular(vector<int>& nums) {
        //环形数组头尾相连
        //最大和有两种情况
        //一种是子数组在数组中间
        //另外一种子数组在数组的两端(正难则反,最大在两端,最小就在中间)
        //转化为两个dp表一个求最大和,一个求最小和
        int n=nums.size();
        vector<int> maxdp(n);
        vector<int> mindp(n);
        maxdp[0]=nums[0];
        mindp[0]=nums[0];
        int _max,_min,sum;
        sum=_max=_min=nums[0];
        for(int i=1;i<n;i++)
        {
            sum+=nums[i];
            maxdp[i]=max(nums[i],maxdp[i-1]+nums[i]);
            _max=max(_max,maxdp[i]);
            mindp[i]=min(nums[i],mindp[i-1]+nums[i]);
            _min=min(_min,mindp[i]);
        }
        if(sum==_min) //对全是负数的情况-1,-2,-3处理
        return _max;
        return max(_max,sum-_min);
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值