前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >买卖股票最多K次

买卖股票最多K次

作者头像
bear_fish
发布2018-09-20 11:33:07
1.1K0
发布2018-09-20 11:33:07
举报
文章被收录于专栏:用户2442861的专栏

题目描述:

给定一个大小为n的数组,数组的元素a[i]代表第i天的股票价格。 设计一个算法,计算在最多允许买卖k次(一买一卖记为一次)的条件下的最大收益。 需要注意的是,你不能同时拥有两份股票。也就是说在下次买入前,你必须把手头上原有的股票先卖掉。

输入:

输入可能包含多个测试案例。 对于每个测试案例,输入的第一行为两个整数n和k(1<=n,k<=1000)。 输入的第二行包括n个整数,范围在[0,10000),代表数组中的元素。

输出:

对应每个测试案例,输出最大获益。

样例输入:

代码语言:javascript
复制
5 1
3 4 5 1 4
7 2
1 2 3 5 6 1 7

样例输出:

代码语言:javascript
复制
3
11

一个简单的DP, 转移方程是:

f (i ,k ) = max{  f (i-1,k) ,  max {  f( j,k-1) + prices[i]-prices[ j]  |  0<=j<i } } , 

即,第i天不做生意,那么是f(i-1,k),或者第i天要卖,那么这次买应该来自第j 天,所以是  f(j,k-1) +prices[i] - prices[j]  ,然后取最大值。

这个复杂度是 O ( N2 *K )的,很明显看到递归式中 后面枚举 j 的过程可以用单调队列优化的,这样最后复杂度是 O ( N * K ) 的。

先来个最直观的没有优化的好了嘛:

[cpp] view plaincopy

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<vector>
  4. #include<string>
  5. #include<cstring>
  6. #include<climits>
  7. #include<queue>
  8. #include<map>
  9. #include<algorithm>
  10. using namespace std;  
  11. int main()  
  12. {  
  13. int n,k;  
  14. while(scanf("%d%d",&n,&k)!=EOF)  
  15.     {  
  16.         vector<vector<int> > dp(n,vector<int>(k+1,0));  
  17.         vector<int> prices(n,0);  
  18. for(int i=0;i<n;i++)  
  19.             scanf("%d",&prices[i]);  
  20. for(int i=1;i<n;i++)  
  21.         {  
  22. for(int t=1;t<=k;t++)  
  23.             {  
  24. int mx=dp[i-1][t];  
  25. for(int j=i-1;j>=0;j--)  
  26.                     mx=max(mx,dp[j][t-1]+prices[i]-prices[j]);  
  27.                 dp[i][t]=mx;  
  28.             }  
  29.         }  
  30.         printf("%d\n",dp[n-1][k]);  
  31.     }  
  32. }  

然后发现居然一个用例都过不了,全超时,真是。。。不好说什么了,一个月赛几道题的其中一道,不至于这么卡数据吧。。。这月赛难度太大了吧。。。

然后就老老实实写个优化的呗,还是比较直观,用 preMax[k] 表示这个最小值。

关于单调队列的优化,同学们可以去找找资料来看,超级有用,一般都能把复杂度降低一个 N.

[cpp] view plaincopy

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<vector>
  4. #include<string>
  5. #include<cstring>
  6. #include<climits>
  7. #include<queue>
  8. #include<map>
  9. #include<algorithm>
  10. using namespace std;  
  11. int main()  
  12. {  
  13. int n,k;  
  14. while(scanf("%d%d",&n,&k)!=EOF)  
  15.     {  
  16.         vector<vector<int> > dp(n,vector<int>(k+1,0));  
  17.         vector<int> prices(n,0);  
  18.         vector<int> preMax(k+1,0);  
  19. for(int i=0;i<n;i++)  
  20.             scanf("%d",&prices[i]);  
  21. for(int i=0;i<=k;i++)  
  22.             preMax[i]=-prices[0];  
  23. for(int i=1;i<n;i++)  
  24.         {  
  25.             preMax[0]=max(preMax[0],dp[i][0]-prices[i]);  
  26. for(int t=1;t<=k;t++)  
  27.             {  
  28. int mx=dp[i-1][t];  
  29.                 mx=max(mx,preMax[t-1]+prices[i]);  
  30.                 preMax[t-1]=max(preMax[t-1],dp[i][t-1]-prices[i]);  
  31.                 dp[i][t]=mx;  
  32.             }  
  33.         }  
  34.         printf("%d\n",dp[n-1][k]);  
  35.     }  
  36. }  
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2015年09月13日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档