hdu3401:单调队列优化dp
第一个单调队列优化dp
写了半天,最后初始化搞错了还一直wa。。
题目大意:
炒股,总共 t 天,每天可以买入na[i]股,卖出nb[i]股,价钱分别为pa[i]和pb[i],最大同时拥有p股
且一次交易后至少要间隔w天才能再次交易,初始有0股,本金无限,求最大收益
题解:
dp[i][j]表示第 i 天,有 j 股的最大收益
状态转移 dp[i][j]=max{dp[i-1][j](不买不卖),dp[r][k]-(j-k)*pa[i](i-r>w,j-k<=na[i],买),dp[r][k]+(k-j)*pb[i](i-r>w,k-j<=nb[i],卖)}
复杂度 为 t*t*p*p
首先我们可以看出 dp[i][j]>=dp[i-1][j](不买不卖转移)
所以可以将 r 确定为 i-w-1,复杂度变为t*p*p 还是很大
然后对于买,移项有
dp[i][j]+j*pa[i]=dp[r][k]+k*pa[i]。右边与 j无关, 可见我们只需要对每一个 i 维护一个关于k的单调队列,就可以在 p时间内求出所有的dp[i][j]
复杂度降为 t*p 可以接受了
最后注意下边界条件:
1到w+1的都是从初始条件下转移的
代码:
#include <iostream>
#include <stdio.h>
#include<string.h>
#include<algorithm>
#include<string>
#include<ctype.h>
using namespace std;
#define MAXN 2000
#define inf 200000000
int na[MAXN+],nb[MAXN+],pa[MAXN+],pb[MAXN+];
int dp[MAXN+][MAXN+];
int t,p,w;
typedef struct Node
{
int val,num;
}node;
typedef struct dqueue
{
node q[MAXN*];
int l,r;
bool empty()
{
return l==r;
}
void clear()
{
l=;r=;
}
node front()
{
return q[l];
}
void pop()
{
l++;
}
void push(node x)
{
if(l==r)
{
q[r++]=x;
return;
}
if(x.val>q[l].val)
{
r=l;
q[r++]=x;
return;
}
for(int i=r;i>l;i--)
{
if(x.val<q[i-].val)
{
r=i;
break;
}
}
q[r++]=x;
}
}Dqueue;
Dqueue qa,qb;
int buy(int now,int n)
{
node tmp;
while()
{
tmp=qa.front();
if(tmp.num<n-na[now])
{
qa.pop();
}
else
break;
}
return tmp.val;
}
int sale(int now,int n)
{
node tmp;
while()
{
tmp=qb.front();
if(tmp.num<n)
{
qb.pop();
}
else
break;
}
return tmp.val;
}
void DP()
{
for(int i=;i<=t;i++)
{
for(int j=;j<=p;j++)
{
dp[i][j]=-inf;
}
}
node no;
for(int i=;i<=w+;i++)
{
for(int j=;j<=na[i];j++)
{
dp[i][j]=-pa[i]*j;
}
for(int j=;j<=p;j++)
{
dp[i][j]=max(dp[i][j],dp[i-][j]);
}
}
for(int i=w+;i<=t;i++)
{
qa.clear();
qb.clear();
int r=i-w-; //上一次交易的天数
for(int j=;j<nb[i];j++)
{
no.num=j;
no.val=dp[r][j]+j*pb[i];
qb.push(no);
}
for(int j=;j<=p;j++)
{
no.num=j;
no.val=dp[r][j]+j*pa[i];
qa.push(no);
if(j+nb[i]<=p)
{
no.num=j+nb[i];
no.val=dp[r][j+nb[i]]+(j+nb[i])*pb[i];
qb.push(no);
}
dp[i][j]=max(dp[i][j],dp[i-][j]); //不买
int tmp=buy(i,j);
dp[i][j]=max(dp[i][j],tmp-j*pa[i]); //买
tmp=sale(i,j);
dp[i][j]=max(dp[i][j],tmp-j*pb[i]); //卖
}
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d",&t,&p,&w);
for(int i=;i<=t;i++)
{
scanf("%d%d%d%d",pa+i,pb+i,na+i,nb+i);
}
DP();
int ans=;
for(int i=;i<=p;i++)
{
ans=max(ans,dp[t][i]);
}
printf("%d\n",ans);
}
return ;
}
hdu3401:单调队列优化dp的更多相关文章
- 单调队列优化DP,多重背包
单调队列优化DP:http://www.cnblogs.com/ka200812/archive/2012/07/11/2585950.html 单调队列优化多重背包:http://blog.csdn ...
- bzoj1855: [Scoi2010]股票交易--单调队列优化DP
单调队列优化DP的模板题 不难列出DP方程: 对于买入的情况 由于dp[i][j]=max{dp[i-w-1][k]+k*Ap[i]-j*Ap[i]} AP[i]*j是固定的,在队列中维护dp[i-w ...
- Parade(单调队列优化dp)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2490 Parade Time Limit: 4000/2000 MS (Java/Others) ...
- BZOJ_3831_[Poi2014]Little Bird_单调队列优化DP
BZOJ_3831_[Poi2014]Little Bird_单调队列优化DP Description 有一排n棵树,第i棵树的高度是Di. MHY要从第一棵树到第n棵树去找他的妹子玩. 如果MHY在 ...
- 【单调队列优化dp】 分组
[单调队列优化dp] 分组 >>>>题目 [题目] 给定一行n个非负整数,现在你可以选择其中若干个数,但不能有连续k个数被选择.你的任务是使得选出的数字的和最大 [输入格式] ...
- [小明打联盟][斜率/单调队列 优化dp][背包]
链接:https://ac.nowcoder.com/acm/problem/14553来源:牛客网 题目描述 小明很喜欢打游戏,现在已知一个新英雄即将推出,他同样拥有四个技能,其中三个小技能的释放时 ...
- 单调队列以及单调队列优化DP
单调队列定义: 其实单调队列就是一种队列内的元素有单调性的队列,因为其单调性所以经常会被用来维护区间最值或者降低DP的维数已达到降维来减少空间及时间的目的. 单调队列的一般应用: 1.维护区间最值 2 ...
- BZOJ1791[Ioi2008]Island 岛屿 ——基环森林直径和+单调队列优化DP+树形DP
题目描述 你将要游览一个有N个岛屿的公园.从每一个岛i出发,只建造一座桥.桥的长度以Li表示.公园内总共有N座桥.尽管每座桥由一个岛连到另一个岛,但每座桥均可以双向行走.同时,每一对这样的岛屿,都有一 ...
- P4381 [IOI2008]Island(基环树+单调队列优化dp)
P4381 [IOI2008]Island 题意:求图中所有基环树的直径和 我们对每棵基环树分别计算答案. 首先我们先bfs找环(dfs易爆栈) 蓝后我们处理直径 直径不在环上,就在环上某点的子树上 ...
随机推荐
- 有关UITableViewCell的侧滑删除以及使用相关大神框架MGSwipeTableCell遇到的小问题
提起笔,却不知道从何写起了,今天一整天都耗费在了这个可能根本不算是问题的小问题上,至今仍有一种蛋蛋的忧桑..(噢,不是提笔,是键盘手T_T) 表格视图在项目中就像是每日的家常便饭,在cell上添加侧滑 ...
- Linux查找yum安装软件在系统中路径
find文件查找http://www.ruanyifeng.com/blog/2009/10/5_ways_to_search_for_files_using_the_terminal.html
- java和javax都是Java的API包,java是核心包,javax的x是extension的意思,也就是扩展包。
java和javax都是Java的API包,java是核心包,javax的x是extension的意思,也就是扩展包.
- [转]Android Volley完全解析(四),带你从源码的角度理解Volley
转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/17656437 经过前三篇文章的学习,Volley的用法我们已经掌握的差不多了,但是 ...
- 查询rman备份信息经常使用指令
查询rman备份信息经常使用指令 ----登陆到rman $rman target / ----以精简的格式查看备份信息 RMAN> list backup of database summar ...
- 各种快递查询--Api接口
授权成功我的密钥 爱查快递API使用说明文档 API地址: 以前:http://api.ickd.cn/?com=[]&nu=[]&id=[]&type=[]&enco ...
- mysql中DES加密解密
DES_DECRYPT(crypt_str[,key_str]) 使用DES_ENCRYPT()加密一个字符串.若出现错误,这个函数会返回 NULL. 注意,这个函数只有当MySQL在SSL 的支 ...
- Jquery autocomplete 插件使用
轻松实现类似百度输入框联想功能: autocomplete 是一个很厉害的插件,该插件基于jquery,在jquery官网能下载到最新版本. 首先,jQuery UI 是基于 jQuery 的,所以, ...
- LDAP-常用命令
1.recreating default ads instance ./ [root@dhcppc2 ~]# dsadm delete /usr/local/dsee7/var/dcc/ads #de ...
- ORACLE 物化视图
最近几天,我负责的P项目环境中提供给W系统的一个视图,由于查询逻辑复杂,数据量比较大,导致每次查询视图的时候,查询速度慢,效率低下,遭到了w系统人员的投诉.想了想,还是改成物化视图吧,用了物化视图,腰 ...