这是一道典型的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);
}
}