昨天晚上,初见它时,月黑风高,一个电脑,一支笔,一个人

今天秋高气爽,再一瞥,回眸间

我又来了,honey

  • 题目
  • 题解
  • 代码实现

题目



题解

首先这种 iii 天与前面 jjj 天有关联,而且让你求最后一天的极值
我们一定会联想到 DPDPDP


先搞定 dpdpdp 定义?

第一维毋庸置疑就是表示 iii 天,接着思考一下第二维 jjj
1)如果表示 iii 天买了或者卖了 jjj 股票,就遇到了一个问题,i−W−1i-W-1i−W−1 天的时候股票数又是多少呢?
难道我要再去用一重循环枚举吗?显然不现实。

2)如果表示 iii 天手上还拥有着 jjj 股票( iii 天已经操作完成了)
那么 ±k±k±k 就是 i−W−1i-W-1i−W−1 的股票数了

综上 dp[i][j]:idp[i][j]:idp[i][j]:i 天手上的股票数为 jjj 时的最大收益。

最后输出 dp[n][0]dp[n][0]dp[n][0] 就可以了,nnn 天的时候手上没有股票数肯定是最优解了,不然你手上捏着股票又买卖不了,拿来擦屁股吗??


找到转移方程式?

  • 这一天闲得慌,不买也不卖

    dp[i][j]=dp[i−1][j](0≤j≤MaxP)dp[i][j]=dp[i-1][j] (0≤j≤MaxP)dp[i][j]=dp[i−1][j](0≤j≤MaxP)

  • 这一天才开始玩股票,只能去购进股票

    dp[i][j]=−j∗api(j−asi≤k<j)dp[i][j]=-j*ap_i(j-as_i≤k<j)dp[i][j]=−j∗api​(j−asi​≤k<j)

  • 自由权比较大,手上有点资本,也要购进

    dp[i][j]=dp[i−W−1][k]−(j−k)∗api(j−asi≤k<j)dp[i][j]=dp[i-W-1][k]-(j-k)*ap_i(j-as_i≤k<j)dp[i][j]=dp[i−W−1][k]−(j−k)∗api​(j−asi​≤k<j)

  • 该开始赚钱钱了,卖一点股票出去

    dp[i][j]=dp[i−W−1][k]+(k−j)∗bpi(j<k≤j+bsi)dp[i][j]=dp[i-W-1][k]+(k-j)*bp_i(j<k≤j+bs_i)dp[i][j]=dp[i−W−1][k]+(k−j)∗bpi​(j<k≤j+bsi​)

在这四种情况下,取一个 maxmaxmax 即可。

那么为什么i-W-1就是当前最优解呢?

因为我们是一天一天递推过去的,当前最优解会被传递过去,

这也是我们DP需要完成的


分析这个 DPDPDP 的时间复杂度,O(n3)O(n^3)O(n3)。

所以必须对 kkk 优化

我们就去拆一拆 case3 case4 的 DPDPDP 式

dp[i][j]=dp[i−W−1][k]−(j−k)∗api(j−asi≤k<j)dp[i][j]=dp[i-W-1][k]-(j-k)*ap_i(j-as_i≤k<j)dp[i][j]=dp[i−W−1][k]−(j−k)∗api​(j−asi​≤k<j)⇓\Downarrow ⇓dp[i][j]=dp[i−W−1][k]+k∗api−j∗api(j−asi≤k<j)dp[i][j]=dp[i-W-1][k]+k*ap_i-j*ap_i(j-as_i≤k<j)dp[i][j]=dp[i−W−1][k]+k∗api​−j∗api​(j−asi​≤k<j)
我们会发现 j∗apij*ap_ij∗api​ 是固定不变的。

也就是说真正影响 dp[i][j]dp[i][j]dp[i][j] 的是 dp[i−W−1][k]+k∗apidp[i-W-1][k]+k*ap_idp[i−W−1][k]+k∗api​

而且 dp[i−W−1][k]+k∗apidp[i-W-1][k]+k*ap_idp[i−W−1][k]+k∗api​ 越大越好。

发现这个方程的实质是 k∈[j−asi,j)k∈[j-as_i,j)k∈[j−asi​,j) 这个范围内取得的且只和 kkk 有关。

dp[i][j]=dp[i−W−1][k]+(k−j)∗bpi(j<k≤j+bsi)dp[i][j]=dp[i-W-1][k]+(k-j)*bp_i(j<k≤j+bs_i)dp[i][j]=dp[i−W−1][k]+(k−j)∗bpi​(j<k≤j+bsi​)⇓\Downarrow⇓dp[i][j]=dp[i−W−1][k]+k∗bpi−j∗bpi(j<k≤j+bsi)dp[i][j]=dp[i-W-1][k]+k*bp_i-j*bp_i(j<k≤j+bs_i)dp[i][j]=dp[i−W−1][k]+k∗bpi​−j∗bpi​(j<k≤j+bsi​)

我们会发现 j∗bpij*bp_ij∗bpi​ 是固定不变的。

也就是说真正影响 dp[i][j]dp[i][j]dp[i][j] 的是 dp[i−W−1][k]+k∗bpidp[i-W-1][k]+k*bp_idp[i−W−1][k]+k∗bpi​

而且 dp[i−W−1][k]+k∗bpidp[i-W-1][k]+k*bp_idp[i−W−1][k]+k∗bpi​ 越大越好。

发现这个方程的实质是 k∈(j,j+bsi]k∈(j,j+bs_i]k∈(j,j+bsi​] 这个范围内取得的且只和k有关

结合以上两种情况:就会联想到我们的单调队列了。

维护 kkk 的范围而且从大到小,每次取队头 headheadhead 进行更值

这样就转化成了O(n2)O(n^2)O(n2)。


最后注意一下循环顺序

买股票就从小到大 0∼MaxP0\sim MaxP0∼MaxP

卖股票就从大到小 MaxP∼0MaxP\sim 0MaxP∼0

代码实现

#include <cstdio>
#include <iostream>
using namespace std;
#define MAXN 2005
int T, MaxP, W;
int ap, bp, as, bs;
int head, tail;
int deq[MAXN];
int dp[MAXN][MAXN];
int main() {scanf ( "%d %d %d", &T, &MaxP, &W );++ W;dp[0][0] = -MAXN * MAXN;for ( int i = 1;i <= MaxP;i ++ )dp[0][i] = dp[0][i - 1];for ( int i = 1;i <= T;i ++ ) {scanf ( "%d %d %d %d", &ap, &bp, &as, &bs );for ( int j = 0;j <= MaxP;j ++ )dp[i][j] = dp[i - 1][j];for ( int j = 0;j <= as;j ++ )dp[i][j] = max ( dp[i][j], -j * ap );if ( i > W ) {head = 1, tail = 0;for ( int j = 0;j <= MaxP;j ++ ) {while ( head <= tail && deq[head] < j - as )head ++;while ( head <= tail && deq[tail] * ap + dp[i - W][deq[tail]] <= j * ap + dp[i - W][j] )-- tail;deq[++ tail] = j;dp[i][j] = max ( dp[i][j], dp[i - W][deq[head]] + deq[head] * ap - j * ap );}head = 1, tail = 0;for ( int j = MaxP;j >= 0;j -- ) {while ( head <= tail && deq[head] > j + bs )head ++;while ( head <= tail && deq[tail] * bp + dp[i - W][deq[tail]] <= j * bp + dp[i - W][j] )tail --;deq[++ tail] = j;dp[i][j] = max ( dp[i][j], dp[i - W][deq[head]] + deq[head] * bp - j * bp );}}}printf ( "%d", dp[T][0] );return 0;
}

DP专练4:[SCOI 2010]股票交易(单调队列优化dp)相关推荐

  1. Buying Feed, 2010 Nov (单调队列优化DP)

    约翰开车回家,又准备顺路买点饲料了(咦?为啥要说"又"字?)回家的路程一共有 E 公里, 这一路上会经过 K 家商店,第 i 家店里有 Fi 吨饲料,售价为每吨 Ci 元.约翰打算 ...

  2. 算法笔记--单调队列优化dp

    单调队列:队列中元素单调递增或递减,可以用双端队列实现(deque),队列的前面和后面都可以入队出队. 单调队列优化dp: 问题引入: dp[i] = min( a[j] ) ,i-m < j ...

  3. poj 2373(单调队列优化dp)

    在长为L(<=1000000)的草地(可看成线段)上装喷水头,喷射是以这个喷水头为中心,喷水头的喷洒半径是可调节的调节范围为[a,b].要求草地的每个点被且只被一个喷水头覆盖,并且有些连续区间必 ...

  4. poj 1821(单调队列优化dp)

    题意:有一道线性篱笆由N个连续的木板组成.有K个工人,你要叫他们给木板涂色.每个工人有3个参数:L 表示 这个工人可以涂的最大木板数目,S表示这个工人站在哪一块木板,P表示这个工人每涂一个木板可以得到 ...

  5. 洛谷P3195 [HNOI2008]玩具装箱TOY(单调队列优化DP)

    题目描述 P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1...N的N件玩具, ...

  6. 【计蒜客 - 蓝桥训练】蒜厂年会(单调队列优化dp,循环数列的最大子段和)

    题干: 在蒜厂年会上有一个抽奖,在一个环形的桌子上,有 nn 个纸团,每个纸团上写一个数字,表示你可以获得多少蒜币.但是这个游戏比较坑,里面竟然有负数,表示你要支付多少蒜币.因为这些数字都是可见的,所 ...

  7. 单调队列以及单调队列优化DP

    单调队列定义: 其实单调队列就是一种队列内的元素有单调性的队列,因为其单调性所以经常会被用来维护区间最值或者降低DP的维数已达到降维来减少空间及时间的目的. 单调队列的一般应用: 1.维护区间最值 2 ...

  8. POJ 1821 Fence(单调队列优化DP)

    题解 以前做过很多单调队列优化DP的题. 这个题有一点不同是对于有的状态可以转移,有的状态不能转移. 然后一堆边界和注意点.导致写起来就很难受. 然后状态也比较难定义. dp[i][j]代表前i个人涂 ...

  9. 【单调队列优化DP】烽火传递 LibreOJ - 10180

    题目来源 点我进入提交题目 反思 因为目前在学习单调队列优化DP,所以会往单调队列上面想.然后犯了一个错误就是,认为这个题目只要用单调队列就可以完成,单调队列只是用来减少时间复杂度的,遇到了求最优解的 ...

  10. AcWing 1089 烽火传递 题解(动态规划—DP—单调队列优化DP)

    AcWing 1089 烽火传递 单调队列优化DP,思路比较简单,维护一个保持元素单调递增的单调队列,队首就是第i座烽火台能接收到的,代价最小的方案,加上第i座烽火台的代价就是这座烽火台的最小值 #i ...

最新文章

  1. 水稻微生物组时间序列分析3-冲击图展示时间序序列变化
  2. KNN 最近邻算法(K近邻)
  3. oracle 导入Excel数据
  4. springmvc配置同时支持html和jspl两种格式的页面
  5. 【C#控件详解】对话框类控件(打开文件,保存文件,选择字体和颜色)
  6. laravel5.5中间件
  7. win7 系统增加自定义分辨率_完美适配win7操作系统的平板电脑,专治软件不兼容...
  8. 【ES】CURL 操作 ES命令集合
  9. edup网卡 linux,应用笔记--使用USB WiFi网卡
  10. 浏览器地址栏中加入ico图标的二种方法
  11. 冲击波病毒简介及解决方法
  12. 什么是数据可视化?hightopo数据可视化助力企业数字化
  13. Via板载声卡底噪严重、播放卡顿及耳机与扬声器音源切换问题【解决方法】
  14. openwrt刷回原厂固件_小米路由3刷机与刷回
  15. Java项目:调查问卷管理系统(java+SpringBoot+Vue+ElementUI+Maven+mysql)
  16. 七十三、java版商城之买家端商品详情Spring Cloud+SpringBoot+mybatis+uniapp b2b2c o2o 多商家入驻商城 直播带货商城 电子商务
  17. 2014522420145238 《信息安全系统设计基础》第二次实验
  18. unwinding now org.apache.cxf.interceptor.Fault: Index: 1, Size: 1
  19. 工具箱@CMD实用命令
  20. 国家非专业等级计算机考试大纲,非计算机专业最新计算机等级考试大纲及试题.doc...

热门文章

  1. 程序员年入50万,我们该如何努力达到这个目标?
  2. python时间函数报错_Python Day11-LEGB-global-时间函数
  3. linux端口 fcs校验,我如何接收错误的以太网帧并禁用CRC / FCS计算?
  4. python调用robotframework_robotframework+python接口自动化的点滴记录(2)
  5. mysql打开无法控制_MySQL不能启动和停止 MySQL各种解决方法教程
  6. 实现option上下移动_用jQuery实现lt;selectgt;选项上下移动 - 不要哀求 学会争取 若是如此 终有所获 - ITeye博客...
  7. msf payload php,Metasploit(四)--Msfpayload命令
  8. mysql 5.5 免安装_mysql 5.5.56免安装版配置方法
  9. IDEA如何在包下建立子包
  10. [JavaWeb-JavaScript]JavaScript运算符