动态规划-股票交易
题意:告诉N天的股票价格,进行两个交易,可以同一天进行多次操作,但必须第一次买入之后,必须要先卖出,然后才可以第二次买入。问最大利润是多少?
- dp[i]前i天进行第一次交易最大利润
- dp[i] = max(dp[i-1],num[i]-minn)
- 不是第i天卖出:等于前i-1天进行第一次交易所得利润最大值
- 是第i天卖出:最大利润为第n天的价钱减去前n天股票价钱的最小值
- 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天股票价钱之差
- 如果每天只能进行一次交易,解法类似。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; }