Trade-----HDU3401----单调队列优化的DP
题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=3401
题目意思:
有T天,你每天可以以API买进,BPI卖出,最多买ASI个,最多卖BSI个
最多只能持有MAXP个商品,相邻两次交易要大于W天
问你最多在第T天结束的时候能赚多少钱
解题思路:
有三个状态转移方程,其中dp[i][j]表示第i天手上有j个商品时我赚的钱
dp[i][j] = max(dp[i][j],dp[i-1][j]) //即针对前一天我啥也不做
对于买而言,有一个递推式
dp[i][j] = max(dp[i][j],max(dp[i-w-1][k] - (j-k)*buyp[i] )
进一步拆开就是 dp[i][j] = max(dp[i][j], max(dp[i-w-1][k]+k*buyp[i]) - j*buyp[i] );
因为是买,所以0<=(j-k)<=canbuyn[i]
我们可以利用优先队列将对于i来说能看到的最大放在队首
对于卖而言同理,只不过方程变成
dp[i][j] = max(dp[i][j], max(dp[i-w-1][k]+k*sellp[i])-j*sellp[i]
0<=(k-j)<=canselln[i]
下面上代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdlib>
using namespace std; const int maxn = 3000; struct node
{
int val,pos;
}q[maxn]; int sellp[maxn],buyp[maxn];
int canselln[maxn],canbuyn[maxn];
int dp[maxn][maxn];
int T,n,maxp,w;
const int inf = 0x3f3f3f3f; void dpf()
{
for(int i=1;i<=n;i++)
{
for(int j=0;j<=maxp;j++)
dp[i][j] = -inf;
} //在前w+1天不能卖,只能买
for(int i=1;i<=n;i++)
{
for(int j=0;j<=min(maxp,canbuyn[i]);j++)
{
dp[i][j] = -buyp[i]*j; //买的都是负账
}
} for(int i=2;i<=n;i++) //针对前一天我啥也不做
{
for(int j=0;j<=maxp;j++)
dp[i][j] = max(dp[i][j],dp[i-1][j]);
} for(int i=w+2;i<=n;i++) //前w+1天除了买啥也不能做,既能买又能卖得从w+2开始
{
int pre = i-w-1;
//对于买而言,有一个递推式
//dp[i][j] = max(dp[i][j],max(dp[i-w-1][k] - (j-k)*buyp[i] )
//进一步拆开就是 dp[i][j] = max(dp[i][j], max(dp[i-w-1][k]+k*buyp[i]) - j*buyp[i] );
//因为是买,所以0<=(j-k)<=canbuyn[i]
//我们可以利用优先队列将对于i来说能看到的最大放在队首
int head,tail;
head = 0;
tail = -1;
for(int j=0;j<=maxp;j++)
{
dp[i][j] = max(dp[i][j],dp[i-1][j]);
node tmp;
tmp.val = dp[pre][j]+j*buyp[i];
tmp.pos = j;
//插入到优先队列里面去
while(head<=tail && q[tail].val < tmp.val) tail--;
q[++tail] = tmp;
//队首还要满足0<=(j-k)<=canbuyn[i]
while(head<=tail && (j-q[head].pos)>canbuyn[i] )head++; //取队首
if(head<=tail) dp[i][j] = max(dp[i][j],q[head].val-j*buyp[i]);
} //对于卖而言同理,只不过方程变成
//dp[i][j] = max(dp[i][j], max(dp[i-w-1][k]+k*sellp[i])-j*sellp[i]
//0<=(k-j)<=canselln[i]
head=0;
tail=-1;
for(int j=maxp;j>=0;j--)
{
dp[i][j] = max(dp[i][j],dp[i-1][j]);
node tmp;
tmp.val = dp[pre][j]+j*sellp[i];
tmp.pos = j; while(head<=tail && q[tail].val < tmp.val) tail--;
q[++tail] = tmp; while(head<=tail && (q[head].pos-j) > canselln[i]) head++; if(head<=tail) dp[i][j] = max(dp[i][j],q[head].val-j*sellp[i]); } } } int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d",&n,&maxp,&w);
for(int i=1;i<=n;i++)
scanf("%d%d%d%d",&buyp[i],&sellp[i],&canbuyn[i],&canselln[i]);
dpf();
int ans = 0;
for(int j=0;j<=maxp;j++)
ans = max(ans,dp[n][j]);
printf("%d\n",ans);
}
return 0;
}
Trade-----HDU3401----单调队列优化的DP的更多相关文章
- 【NOIP2017】跳房子 题解(单调队列优化线性DP)
前言:把鸽了1个月的博客补上 ----------------- 题目链接 题目大意:机器人的灵敏性为$d$.每次可以花费$g$个金币来改造机器人,那么机器人向右跳的范围为$[min(d-g,1),m ...
- 【HDU 3401 Trade】 单调队列优化dp
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3401 题目大意:现在要你去炒股,给你每天的开盘价值,每股买入价值为ap,卖出价值为bp,每天最多买as ...
- 【HDU】3401:Trade【单调队列优化DP】
Trade Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- 洛谷p1725 露琪诺 单调队列优化的DP
#include <iostream> #include <cstdio> #include <cstring> using namespace std; int ...
- BestCoder Round #89 02单调队列优化dp
1.BestCoder Round #89 2.总结:4个题,只能做A.B,全都靠hack上分.. 01 HDU 5944 水 1.题意:一个字符串,求有多少组字符y,r,x的下标能组成等比数列 ...
- 单调队列以及单调队列优化DP
单调队列定义: 其实单调队列就是一种队列内的元素有单调性的队列,因为其单调性所以经常会被用来维护区间最值或者降低DP的维数已达到降维来减少空间及时间的目的. 单调队列的一般应用: 1.维护区间最值 2 ...
- bzoj1855: [Scoi2010]股票交易 单调队列优化dp ||HDU 3401
这道题就是典型的单调队列优化dp了 很明显状态转移的方式有三种 1.前一天不买不卖: dp[i][j]=max(dp[i-1][j],dp[i][j]) 2.前i-W-1天买进一些股: dp[i][j ...
- hdu3401:单调队列优化dp
第一个单调队列优化dp 写了半天,最后初始化搞错了还一直wa.. 题目大意: 炒股,总共 t 天,每天可以买入na[i]股,卖出nb[i]股,价钱分别为pa[i]和pb[i],最大同时拥有p股 且一次 ...
- 【单调队列优化dp】HDU 3401 Trade
http://acm.hdu.edu.cn/showproblem.php?pid=3401 [题意] 知道之后n天的股票买卖价格(api,bpi),以及每天股票买卖数量上限(asi,bsi),问他最 ...
- 单调队列优化DP,多重背包
单调队列优化DP:http://www.cnblogs.com/ka200812/archive/2012/07/11/2585950.html 单调队列优化多重背包:http://blog.csdn ...
随机推荐
- javascript 控制台输出 图片 console.log 真强大 真佩服你们的创造力
无意中,在百度知道页面发现了这货.居然能输出图片到控制台. 完全颠覆自己的三观,果断查阅其输出方法.后得知,原来如此. 曾经做过的项目中,同事把控制台做成一个网页形式方便远程控制和远程调用.没想到过这 ...
- GIMP也疯狂之动态图的制作(三)
Note:本篇文章内容为linux下利用gimp和其它工具组合完成截取制作GIF图的一种实现,制作更为灵活,但并不方便,如果不需要那么高的定制性,并追求方便高效.可以使用类似QQ影音之类的软件,自带截 ...
- JSON之FastJson
FastJson是什么? 从网上查到--- 官网地址:http://code.alibabatech.com/wiki/display/FastJSON/Overview(已关闭) FastJSOn是 ...
- Idea构建Maven项目教程
Idea构建Maven项目,以及其中遇到的坑,及解决方案 步骤一:配置Idea的maven插件 步骤二:创建maven项目 file-->new-->project 下一步,设置group ...
- C++一些注意点之转换操作符
转换操作符定义 类可通过一个实参调用的非explicit构造函数定义一个隐式转换(其他类型—>类类型).当提供了实参类型的对象而需要一个类类型的对象时,编译器将使用该转换.这种构造函数定义了到类 ...
- IOS UI 第五篇:基本UI
添加个导航栏: Xib1 *xib1 = [[Xib1 alloc] initWithNibName:@"Xib1" bundle:nil]; UINavig ...
- 跨域访问 REST API
跨域访问 Web Service (REST API) 虽然 JQuery 也能通过授权header实现跨域, 但SharePoint 提供了更简单的方法,它被实现在SP.RequestExecuto ...
- D11
=-=感觉今天的题目好难... 主要是没有碰到过,所以会觉得不懂怎么写.. 其实现在想想,T1,T2,T3其实都好水..T1其实没有做过还真不会,有做过的话就是个大水题了 T2找最小环..超级裸的,但 ...
- 长乐集训2012.7.11 happy(指针技巧的运用)
题1 Noip的快乐 (happy.pas/c/cpp) [问题描述] 终于到了一年一度的Noip比赛了,多么令人期待和兴奋的一天!其实,人们最高兴的还不是遇见老朋友,而是结交新朋友.可是结交新的朋 ...
- Paint.NET
http://www.dotpdn.com/downloads/pdn.html Paint.NET To download, please click the Free Download Now l ...