【题目链接】

ybt 1302:股票买卖
OpenJudge NOI 2.6 8464:股票买卖

【题目考点】

1. 动态规划:线性动规

【解题思路】

解法1:

该题可以抽象为:在一个长为n的数字序列上,第i个数字为a[i]。找满足1≤i1≤j1≤i2≤j2≤n1\le i1 \le j1 \le i2 \le j2 \le n1≤i1≤j1≤i2≤j2≤n的两个数对(i1, j1), (i2, j2),使得a[j1]-a[i1]+a[j2]-a[i2]最大。
还可以简单描述为:定义区间差值为区间两端点数值的差,求一个数字序列上两个不相交的区间差值加和的最大值。(区间长度大于等于1)
该题可以用与1305:Maximum sum类似的思路来做。

  • 定义数组de,de[i]指以a[i]为结尾的所有区间中,区间差值的最大的区间的区间差值。自然de[i]为当前数字a[i]减去第1到第i数字中的最小值。记mn为a[1]~a[i]中的最小值,那么de[i] = a[i] - mn
  • 类似地,定义数组db,db[i]指以a[i]为起始的所有区间中,区间差值的最大的区间的区间差值。自然db[i]为第i到第n数字中的最大值减去a[i],记mx为a[i]~a[n]中的最大值,那么db[i] = mx - a[i]

1. 状态定义

集合:数字序列中的区间
限制:关注的数字范围
属性:区间差值
条件:最大
统计量:区间差值
状态定义
dpe[i]:第1到第i个数字构成的所有区间中,区间差值最大的区间的区间差值。
dpb[i]:第i到第n个数字构成的所有区间中,区间差值最大的区间的区间差值。

  • 以第1数字到第i数字为结尾的所有区间中区间差值的最大值,即为第1到第i个数字构成的所有区间中区间差值的最大值,即dpe[i]de[1]~de[i]中的最大值。
    所以dpe[i]de[1]~de[i-1]中的最大值dpe[i-1]de[i]相比的较大值,即dpe[i] = max(dpe[i-1], de[i])
  • 以第i数字到第n数字为起始的所有区间中区间差值的最大值,即为第i到第n个数字构成的所有区间中区间差值的最大值,即dpb[i]db[i]~db[n]中的最大值
    所以dpb[i]db[i+1]~db[n]中的最大值dpb[i+1]db[i]相比的较大值,即dpb[i] = max(dpb[i+1], db[i])

2. 状态转移方程

集合:第1到第n个数字构成的所有区间
分割集合:枚举分割点,分成第1到第i个数字构成的区间,与第i到第n个数字构成的区间

i从1循环到n-1,取a[1]~a[i]中区间差值的最大值dpe[i]。以及a[i+1]~a[n]中区间差值的最大值dpb[i+1]。加和为ans = dpe[i]+dpb[i+1]。对于每个i求出的ans,求最大值,得到的结果就是整个序列中两个不相交的区间的区间差值加和的最大值,即为原问题中两次买卖得到的最大利润。

解法2:

该问题也可以不求dpe与dpb,只用de与db。直接用第1到第i数字中的最大区间差值mxde(相当于dpe[i])加上以i+1为起始的区间的最大区间差值(db[i]),求这个数字的最大值。结果是一样的。

【题解代码】

解法1:

  • 基本解法
#include<bits/stdc++.h>
using namespace std;
#define N 100005
#define INF 0x3f3f3f3f
int t, n, ans, a[N], de[N], db[N], dpe[N], dpb[N];
int main()
{int mn, mx;scanf("%d", &t);while(t--){memset(dpe, 0, sizeof(dpe));memset(dpb, 0, sizeof(dpb));scanf("%d", &n);for(int i = 1; i <= n; ++i)scanf("%d", &a[i]);mn = a[1];for(int i = 1; i <= n; ++i){mn = min(mn, a[i]);de[i] = a[i] - mn;//以a[i]为结尾的所有区间中,区间差值的最大的区间的区间差值。dpe[i] = max(dpe[i-1], de[i]);//第1到第i个数字构成的所有区间中,区间差值最大的区间的区间差值。}mx = a[n];for(int i = n; i >= 1; --i){mx = max(mx, a[i]);db[i] = mx - a[i];//以a[i]为起始的所有区间中,区间差值的最大的区间的区间差值。dpb[i] = max(dpb[i+1], db[i]);//第i到第n个数字构成的所有区间中,区间差值最大的区间的区间差值。}ans = -INF;//原序列中不相交的两个区间的区间差值加和的最大值 for(int i = 1; i < n; ++i)//枚举分割点ans = max(ans, dpe[i]+dpb[i+1]);printf("%d\n", ans);}return 0;
}
  • 优化:变递推为迭代
    de与db可以降维,从数组变为一个变量,而后发现这是个中间变量,可以删去。
#include<bits/stdc++.h>
using namespace std;
#define N 100005
#define INF 0x3f3f3f3f
int t, n, ans, mn, mx, a[N], dpe[N], dpb[N];
int main()
{scanf("%d", &t);while(t--){memset(dpe, 0, sizeof(dpe));memset(dpb, 0, sizeof(dpb));scanf("%d", &n);for(int i = 1; i <= n; ++i)scanf("%d", &a[i]);mn = a[1];for(int i = 1; i <= n; ++i){mn = min(mn, a[i]);dpe[i] = max(dpe[i-1], a[i] - mn);//第1到第i个数字构成的所有区间中,区间差值最大的区间的区间差值。}mx = a[n];for(int i = n; i >= 1; --i){mx = max(mx, a[i]);dpb[i] = max(dpb[i+1], mx - a[i]);//第i到第n个数字构成的所有区间中,区间差值最大的区间的区间差值。}ans = -INF;//原序列中不相交的两个区间的区间差值加和的最大值 for(int i = 1; i < n; ++i)//枚举分割点ans = max(ans, dpe[i]+dpb[i+1]);printf("%d\n", ans);}return 0;
}
  • 解法2:
#include<bits/stdc++.h>
using namespace std;
#define N 100005
#define INF 0x3f3f3f3f
int t, n, mn, mx, mxde, ans, a[N], de[N], db[N];
int main()
{scanf("%d", &t);while(t--){scanf("%d", &n);for(int i = 1; i <= n; ++i)scanf("%d", &a[i]);mn = a[1];for(int i = 1; i <= n; ++i){mn = min(mn, a[i]);de[i] = a[i] - mn;//以a[i]为结尾的所有区间中,区间差值的最大的区间的区间差值。}mx = a[n];for(int i = n; i >= 1; --i){mx = max(mx, a[i]);db[i] = mx - a[i];//以a[i]为起始的所有区间中,区间差值的最大的区间的区间差值。}mxde = ans = -INF;//ans:原序列中不相交的两个区间的区间差值加和的最大值 for(int i = 1; i < n; ++i)//枚举分割点{mxde = max(mxde, de[i]);//mxde为第1到第i个数字构成的所有区间中,区间差值最大的区间的区间差值。 ans = max(ans, mxde + db[i+1]);}printf("%d\n", ans);}return 0;
}

信息学奥赛一本通 1302:股票买卖 | OpenJudge NOI 2.6 8464:股票买卖相关推荐

  1. 信息学奥赛一本通 1209:分数求和 | OpenJudge NOI 1.13 12:分数求和

    [题目链接] ybt 1209:分数求和 OpenJudge NOI 1.13 12:分数求和 [题目考点] 1. 求最大公约数 2. 求最小公倍数 [解题思路] 求最大公约数,可以用辗转相除法.具体 ...

  2. 信息学奥赛一本通 1294:Charm Bracelet | OpenJudge NOI 2.6 7113:Charm Bracelet | 洛谷 P2871

    [题目链接] ybt 1294:Charm Bracelet OpenJudge NOI 2.6 7113:Charm Bracelet 洛谷 P2871 [USACO07DEC]Charm Brac ...

  3. 信息学奥赛一本通(基础算法与数据结构-题解汇总目录)

    信息学奥赛一本通(C++版)在线评测系统 基础(二)基础算法   更新中...... 第一章高精度计算 1307[例1.3]高精度乘法 1308[例1.5]高精除 1309[例1.6]回文数(Noip ...

  4. 信息学奥赛一本通 1278:【例9.22】复制书稿(book) | 洛谷 P1281 书的复制

    [题目链接] ybt 1278:[例9.22]复制书稿(book) 洛谷 P1281 书的复制 [题目考点] 1. 动态规划:线性动规 [解题思路] 该题可以抽象为:将由m个数字构成的序列分成k个子段 ...

  5. 信息学奥赛一本通(C++版) 第二部分 基础算法 第九章 动态规划

    总目录详见:https://blog.csdn.net/mrcrack/article/details/86501716 信息学奥赛一本通(C++版) 第二部分 基础算法 第九章 动态规划 第一节 动 ...

  6. 信息学奥赛一本通 提高篇 第六部分 数学基础 相关的真题

    第1章   快速幂 1875:[13NOIP提高组]转圈游戏 信息学奥赛一本通(C++版)在线评测系统 第2 章  素数 第 3 章  约数 第 4 章  同余问题 第 5 章  矩阵乘法 第 6 章 ...

  7. 信息学奥赛一本通 2021:【例4.6】最大公约数

    [题目链接] ybt 2021:[例4.6]最大公约数 [题目考点] 1. while循环 2. 求最大公约数 辗转相减法 辗转相除法 [解题思路] 解法1:枚举 取较小数字,从该数字的值开始从大到小 ...

  8. 信息学奥赛一本通(C++版) 刷题 记录

    总目录详见:https://blog.csdn.net/mrcrack/article/details/86501716 信息学奥赛一本通(C++版) 刷题 记录 http://ybt.ssoier. ...

  9. 信息学奥赛一本通 (C++)上机练习

    信息学奥赛一本通(C++)上机练习 此书为娃儿的第一本刷题书.娃儿现在四年级 ,希望他能坚持下来.特开贴加油 luogu: disangan223 第一部分 C++语言 第一章 C++语言入门 T10 ...

最新文章

  1. Cell:康奈尔大学郭春君组开发针对非模式肠道细菌的基因编辑工具
  2. 全球资金看好中国的AI(人工智能)
  3. LeetCode--Excel Sheet Column Number
  4. 关于Spring容器管理Bean的过程以及加载模式
  5. kubernetes学习笔记之七:Ingress-nginx部署使用
  6. picker封装 uniapp_uniapp自定义picker城市多级联动组件
  7. [蓝桥杯2015决赛]分机号-枚举(水题)
  8. 严重: Error configuring application listener of class org.springframework.web.context.ContextLoaderLis
  9. 11-标志寄存器+adc/sbb+cmp+条件转移指令
  10. Zune WIFI无线同步教程
  11. ios计算机错误,用iTunes更新IOS14失败,显示发生未知错误(4000)的简单解决办法!...
  12. 华为路由器接学校校园网,LOS一直亮红灯解决办法。
  13. 计算机设备管理器无com,计算机无设备管理器的方法
  14. 拉丁巨星——恰恰恰[Flash]
  15. 和周杰讨论:DB2连接问题
  16. 人人商城秒杀redis配置
  17. 图形B=B≌B凸显中学数学有一系列重大错误(更新稿) ——合同图形概念让5000年无人能识的自然数一下子浮出水面
  18. YOLOv3 cfg文件详解
  19. 数学建模算法与应用【模糊综合评价算法】
  20. 微信chooseImage,getLocalImgData调取相机拍照,获取图片base64

热门文章

  1. docker启动streamsets
  2. 不用下载任何软件,比360强力删除还强的删除文件方法
  3. SWOT分析、PEST分析、GE矩阵、波士屯矩阵等分析方法
  4. 如何鉴别和评审APS软件?内行人告诉你
  5. 工程图学及计算机绘图第二版答案,工程图学及计算机绘图: 非机类
  6. MT6771_MT6762_ISP_Tuning_Introduction
  7. 17.在NBA我需要翻译-适配器模式(大话设计模式kotlin版)
  8. 期货高频交易该如何选择托管环境
  9. 微服务使用redis操作实例包含redis工具类
  10. 信息收集----CMS指纹识别