热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

CF:391F1StockTrading动规DP

F1.StockTradingtimelimitpertest3secondsmemorylimitpertest256megabytes


F1. Stock Trading



time limit per test

3 seconds



memory limit per test

256 megabytes



input

standard input



output

standard output


This problem consists of three subproblems: for solving subproblem F1 you will receive 8 points, for solving subproblem F2 you will receive 15 points, and for solving subproblem F3 you will receive 10
points.

Manao has developed a model to predict the stock price of a company over the next n days and wants to design a profit-maximizing trading algorithm to make
use of these predictions. Unfortunately, Manao‘s trading account has the following restrictions:



  • It only allows owning either zero or one shares of stock at a time;

  • It only allows buying or selling a share of this stock once per day;

  • It allows a maximum of k buy orders over the next n days;

For the purposes of this problem, we define a trade to a be the act of buying one share of stock on day i,
then holding the stock until some day j?>?i at which point the share is sold. To restate the above constraints, Manao is permitted to make at most k non-overlapping
trades during the course of an n-day trading period for which Manao‘s model has predictions about the stock price.

Even though these restrictions limit the amount of profit Manao can make compared to what would be achievable with an unlimited number of trades or the ability to hold more than one share at a time, Manao still has the potential to make a lot of money because
Manao‘s model perfectly predicts the daily price of the stock. For example, using this model, Manao could wait until the price is low, then buy one share and hold until the price reaches a high value, then sell for a profit, and repeat this process up to k times
until n days have passed.

Nevertheless, Manao is not satisfied by having a merely good trading algorithm, and wants to develop an optimal strategy for trading subject to these constraints. Help Manao achieve this goal by writing a program that will determine when to buy and sell stock
to achieve the greatest possible profit during the n-day trading period subject to the above constraints.




Input

The first line contains two integers n and k, separated
by a single space, with bubuko.com,布布扣.
The i-th of the following n lines contains a single
integer pi (0?≤?pi?≤?1012),
where pi represents
the price at which someone can either buy or sell one share of stock on day i.

The problem consists of three subproblems. The subproblems have different constraints on the input. You will get some score for the correct submission of the subproblem. The description of the subproblems
follows.



  • In subproblem F1 (8 points), n will be between 1 and 3000,
    inclusive.

  • In subproblem F2 (15 points), n will be between 1 and 100000,
    inclusive.

  • In subproblem F3 (10 points), n will be between 1 and 4000000,
    inclusive.




Output

For this problem, the program will only report the amount of the optimal profit, rather than a list of trades that can achieve this profit.

Therefore, the program should print one line containing a single integer, the maximum profit Manao can achieve over the next n days with the constraints
of starting with no shares on the first day of trading, always owning either zero or one shares of stock, and buying at mostk shares over the course of
the n-day trading period.




Sample test(s)




input

10 2
2
7
3
9
8
7
9
7
1
9




output

15




input

10 5
2
7
3
9
8
7
9
7
1
9




output

21






Note

In the first example, the best trade overall is to buy at a price of 1 on day 9 and sell at a price of 9 on
day 10 and the second best trade overall is to buy at a price of 2 on day 1 and sell at a price of 9 on
day 4. Since these two trades do not overlap, both can be made and the profit is the sum of the profits of the two trades. Thus the trade strategy looks like this:

2 | 7 | 3 | 9 | 8 | 7 | 9 | 7 | 1 | 9
buy | | | sell | | | | | buy | sell

The total profit is then (9?-?2)?+?(9?-?1)?=?15.

In the second example, even though Manao is allowed up to 5 trades there are only 4 profitable trades available. Making a fifth trade would cost Manao money so he only makes the following 4:

2 | 7 | 3 | 9 | 8 | 7 | 9 | 7 | 1 | 9
buy | sell | buy | sell | | buy | sell | | buy | sell

The total profit is then (7?-?2)?+?(9?-?3)?+?(9?-?7)?+?(9?-?1)?=?21.

题意:题目太长了,都懒得看了,直接看样例就知道是什么意思了……给出n和k,然后给出n个数,从答案可以看出:从中选出k对差值最大的取其之和。而且一对buy和sell中间不能有其他的buy和sell嵌入,这由上面可以看出。而且由上面可以看出:被选出的一对buy和sell中的这两个数,不能用做其他对的数,比如第二个样例中(2,7)是一对,(3,9)是一对,虽然(2,9)的差值也更大,但是其中的2与9在其他对中已经使用过,所以(2,9)不是一对了。意思就是其中所选的数不能重复使用!

思路:所以这样的话,就是用DP来做了。DP[ i ][ j ]表示在 i 状态下到第 j 个数所能达到的最大&#20540;。因为要选 k 对个buy 与 sell,所以状态从 1 到 k ;因为有 n 个数,所以 1 <=j<=n 。

状态转移方程:

先扫描过去,算出它们之间的差&#20540;,并且找出最大的一对的差&#20540;;然后第二对就可以在前一对的基础上找出来了。

所以当前的最大&#20540;DP[ i ] [ j ] 就是前一个数的能达到的最大&#20540;(即DP[ i ] [ j-1 ])与当前的能达到的最大&#20540;(max(前一状态的前一个数的最大&#20540;,当前状态能达到的最大&#20540;(即Max&#43;p [ j ])),两者取大者。

/*即: DP[ i ] [ j ] =max(DP[ i ] [ j-1 ] , max(Max&#43;p[ j ],DP[ i-1 ] [ j-1 ]);*/

故: DP[ i ] [ j ] =max(DP[ i ] [ j-1 ] , max(Max,DP[ i-1 ] [ j-1 ] -  p[ j ]) &#43;p[ j ]);

而:Max=max(Max,DP[ i-1 ] [ j-1 ] -  p[ j ]) ;

这里,Max这个比较难理解。其实就是前一个状态或者当前状态与前一个数的差&#20540;改变量取最大&#20540;,所以到下一个数的时候才能求出与当前&#20540;差&#20540;最大的加入当前buy和sell。

因为本人也对DP比较晕……所以这题也搞了好久,这个状态又单步调试了,又输出中间量了才理解……确实状态好难想出来啊!!!

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define PI acos(-1.0)
#define mem(a,b) memset(a,b,sizeof(a))
#define sca(a) scanf("%d",&a)
#define pri(a) printf("%d\n",a)
#define f(i,a,n) for(i=a;i#define F(i,a,n) for(i=a;i<=n;i++)
#define MM 10002
#define MN 3005
#define INF 16843009000000
using namespace std;
typedef long long ll;
ll dp[MN][MN],p[MN];
int main()
{
int n,k,i,j;
cin>>n>>k;
F(i,1,n) cin>>p[i];
F(i,1,k)
{
ll M = -INF;
F(j,1,n)
{
M= max(M, dp[i-1][j-1] - p[j]);
dp[i][j] = max(dp[i][j-1], M + p[j]);
//cout < var cpro_id = "u6885494";

推荐阅读
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • 本文总结了Java中日期格式化的常用方法,并给出了示例代码。通过使用SimpleDateFormat类和jstl fmt标签库,可以实现日期的格式化和显示。在页面中添加相应的标签库引用后,可以使用不同的日期格式化样式来显示当前年份和月份。该文提供了详细的代码示例和说明。 ... [详细]
  • 本文介绍了C#中数据集DataSet对象的使用及相关方法详解,包括DataSet对象的概述、与数据关系对象的互联、Rows集合和Columns集合的组成,以及DataSet对象常用的方法之一——Merge方法的使用。通过本文的阅读,读者可以了解到DataSet对象在C#中的重要性和使用方法。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • switch语句的一些用法及注意事项
    本文介绍了使用switch语句时的一些用法和注意事项,包括如何实现"fall through"、default语句的作用、在case语句中定义变量时可能出现的问题以及解决方法。同时也提到了C#严格控制switch分支不允许贯穿的规定。通过本文的介绍,读者可以更好地理解和使用switch语句。 ... [详细]
  • Java验证码——kaptcha的使用配置及样式
    本文介绍了如何使用kaptcha库来实现Java验证码的配置和样式设置,包括pom.xml的依赖配置和web.xml中servlet的配置。 ... [详细]
author-avatar
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有