【题目描述】
最近越来越多的人都投身股市,阿福也有点心动了。谨记着“股市有风险,入市需谨慎”,阿福决定先来研究一下简化版的股票买卖问题。假设阿福已经准确预测出了某只股票在未来 N 天的价格,他希望买卖两次,使得获得的利润最高。为了计算简单起见,利润的计算方式为卖出的价格减去买入的价格。同一天可以进行多次买卖。但是在第一次买入之后,必须要先卖出,然后才可以第二次买入。现在,阿福想知道他最多可以获得多少利润。
【题目链接】
http://noi.openjudge.cn/ch0206/8464/
【算法】
这个dp的决策有点神奇(说实话这感觉不是dp,连多过程决策都没),决策一个第i天使得第一次买卖在第i天前,第二次购买在第i天之后(两次均可包含第i天,因为一天可以多次买卖)。确定好购买区间则最优收益可以预处理前后缀算出。
【代码】
1 #include <bits/stdc++.h> 2 using namespace std; 3 int T,n,i,minn,maxn; 4 int a[100010],pre[100010],post[100010]; 5 int main() 6 { 7 scanf("%d",&T); 8 while(T--) { 9 scanf("%d",&n); 10 for(i=1;i<=n;i++) scanf("%d",&a[i]); 11 memset(post,0,sizeof(post)); 12 minn=a[1]; 13 for(i=2;i<=n;i++) minn=min(minn,a[i]),pre[i]=max(pre[i-1],a[i]-minn); 14 maxn=a[n]; 15 for(i=n-1;i>=1;i--) maxn=max(maxn,a[i]),post[i]=max(post[i+1],maxn-a[i]); 16 int ans=0; 17 for(i=1;i<=n;i++) 18 ans=max(ans,pre[i]+post[i]); 19 printf("%d ",ans); 20 } 21 return 0; 22 }