动态规划-股票交易

股票买卖

题意:告诉N天的股票价格,进行两个交易,可以同一天进行多次操作,但必须第一次买入之后,必须要先卖出,然后才可以第二次买入。问最大利润是多少?

  1. dp[i]前i天进行第一次交易最大利润
    • dp[i] = max(dp[i-1],num[i]-minn)
    • 不是第i天卖出:等于前i-1天进行第一次交易所得利润最大值
    • 是第i天卖出:最大利润为第n天的价钱减去前n天股票价钱的最小值
  2. dp2[i] 第i天进行第二次交易所得两次利润总和的最大值
    • dp2[i]=max(dp[i],dp2[i-1]+num[i]-num[i-1])
    • 是第i天买入的第二次:那么两次总和为前i天进行一次交易最大利润,第二次交易利润为0
    • 不是第i天买入:等于第i-1天卖出,加上第i天股票价钱与第i-1天股票价钱之差
  3. 如果每天只能进行一次交易,解法类似。dp2[i]考虑的是是不是第i-1天买入的第二次。   
    • dp2[i] =max(dp[i-2]+num[i]-num[i-1],dp2[i-1]+num[i]-num[i-1])
    #include <stdio.h>
    #include <stdlib.h>
    #include <limits.h>
    #include <string.h>
    #include <assert.h>
    #include <queue>
    #include <vector>
    #include<list>
    #include <algorithm>
    #include<iostream>
    #include<math.h>
    using namespace std;
    #define N 100005
    #define Inf 0x3f3f3f3f
    int num[N];
    int dp[N];
    int dp2[N];
    int minValue[N];
    
    int main() {
      int t;
      cin>>t;
      while(t--){
          int n;
          scanf("%d",&n);;
          memset(num,0,sizeof(num));
          memset(dp,0,sizeof(dp));
          memset(dp2,0,sizeof(dp2));
          memset(minValue,0,sizeof(minValue));
          int maxx = -1;
          int minn =Inf;
          for(int i=1;i<=n;i++){
              scanf("%d",&num[i]);
              if(minn>num[i]){
                  minn = num[i];
              }
            dp[i] = max(dp[i-1],num[i]-minn);
          }
    
        for(int i=2;i<=n;i++){
            dp2[i] = max(dp[i],dp2[i-1]+num[i]-num[i-1]);
            if(maxx<dp2[i]){
                maxx= dp2[i];
            }
        }
      
      cout<<maxx<<endl;
      
          
      }
      return 0;
    }

猜你喜欢

转载自www.cnblogs.com/cyj1258/p/12142255.html