這是一道典型的DP題目,需要模仿這種題繼續練習,一開始自己的思想出現了點問題,後來發現需要兩個數組進行記錄
第一個數組用來記錄從1-i區間內 當前的 最大最小值之差
第二個數組用來記錄從i-n區間內,當前的最大最小值之差
由於股票只能按照時間買入和出售,並且需要統計最大的兩次,正好就採用這種DP方法
實現的代碼有點亂,因爲思路有些混亂,在實現過程中角標也是一個難點
// 作業09 動態規劃問題 要模仿最長公共子序列?
//兩個東西 第一個表示從第一天到第i天的最大利潤 第二個表示從第i天到第n天的最大利潤
//因爲只買兩次
#include <iostream>
using namespace std;
//在書上見過的DP 找到到哪個位置的最大值
int main(void)
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
int a[100005];
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
int first[100005]={0};//從第一個到第i個位置上 最大的高度差
int second[100005]={0};
int count = 1;
int countt = 1;
int min = a[0];
int temp = -9999999;
int totalmax = 0 ;
for(int i=1;i<n;i++)
{
if(a[i]<min)
{
min = a[i];
}
if(a[i]-min > temp)
{
temp = a[i] - min;
}
// printf("first = %d\n",temp);
first[count++] = temp;
}
int maxx = a[n-1];
int tempx = -9999999;
for(int j=n-1;j>=1;j--)//拆來開 往回搜
{
if(a[j]>maxx)
{
maxx = a[j];
}
if(maxx-a[j] > tempx)
{
tempx = maxx-a[j];
}
second[countt++] = tempx;
// printf("second = %d\n",tempx);
}
// for(int i=0;i<count;i++)
// {
// printf("first = %d\n",first[i]);
// }
int tt = 0;
int s[100005];
for(int i=countt-1;i>=0;i--)
{
// printf("second = %d\n",second[i]);
s[tt++] = second[i];
}
int maxp = 0;
for(int i=0;i<count;i++)
{
// printf("first = %d\t",first[i]);
// printf("second = %d\n",s[i]);
maxp = max(maxp,first[i]+s[i]);
}
printf("%d\n",maxp);
}
}