第一个单调队列优化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的更多相关文章

  1. 单调队列优化DP,多重背包

    单调队列优化DP:http://www.cnblogs.com/ka200812/archive/2012/07/11/2585950.html 单调队列优化多重背包:http://blog.csdn ...

  2. 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 ...

  3. Parade(单调队列优化dp)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2490 Parade Time Limit: 4000/2000 MS (Java/Others)    ...

  4. BZOJ_3831_[Poi2014]Little Bird_单调队列优化DP

    BZOJ_3831_[Poi2014]Little Bird_单调队列优化DP Description 有一排n棵树,第i棵树的高度是Di. MHY要从第一棵树到第n棵树去找他的妹子玩. 如果MHY在 ...

  5. 【单调队列优化dp】 分组

    [单调队列优化dp] 分组 >>>>题目 [题目] 给定一行n个非负整数,现在你可以选择其中若干个数,但不能有连续k个数被选择.你的任务是使得选出的数字的和最大 [输入格式] ...

  6. [小明打联盟][斜率/单调队列 优化dp][背包]

    链接:https://ac.nowcoder.com/acm/problem/14553来源:牛客网 题目描述 小明很喜欢打游戏,现在已知一个新英雄即将推出,他同样拥有四个技能,其中三个小技能的释放时 ...

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

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

  8. BZOJ1791[Ioi2008]Island 岛屿 ——基环森林直径和+单调队列优化DP+树形DP

    题目描述 你将要游览一个有N个岛屿的公园.从每一个岛i出发,只建造一座桥.桥的长度以Li表示.公园内总共有N座桥.尽管每座桥由一个岛连到另一个岛,但每座桥均可以双向行走.同时,每一对这样的岛屿,都有一 ...

  9. P4381 [IOI2008]Island(基环树+单调队列优化dp)

    P4381 [IOI2008]Island 题意:求图中所有基环树的直径和 我们对每棵基环树分别计算答案. 首先我们先bfs找环(dfs易爆栈) 蓝后我们处理直径 直径不在环上,就在环上某点的子树上 ...

随机推荐

  1. MySQL添加外键的方法

    为book表添加外键: <1>明确指定外键的名称: 语法:alter table 表名 add constraint 外键的名称 foreign key(你的外键字段名) REFERENC ...

  2. POJ 2513 Colored Sticks - from lanshui_Yang

    题目大意:给定一捆木棒,每根木棒的每个端点涂有某种颜色.问:是否能将这些棒子首位项链,排成一条直线,且相邻两根棍子的连接处的颜色一样. 解题思路:此题是一道典型的判断欧拉回路或欧拉通路的问题,以木棍的 ...

  3. Sqoop是一款开源的工具,主要用于在HADOOP(Hive)与传统的数据库(mysql、oracle...)间进行数据的传递

    http://niuzhenxin.iteye.com/blog/1706203   Sqoop是一款开源的工具,主要用于在HADOOP(Hive)与传统的数据库(mysql.postgresql.. ...

  4. Verilog之i2c合约

    说明:i2c乔布斯.有这么多的事情在网上参考. 时刻:2014年5一个月6周二星期 1.问题叙述性说明: 正如图.已知的时钟clk为100k,rst为复位信号.上升沿有效,基于Verilog HDL或 ...

  5. MySQL 加密/压缩函数

    这些问题可能导致数据值的改变.一般而言,上述问题可能在你使用非二进制串数据类型(如char,varchar,text等数据类型)的情况下发生. AES_ENCRYPT()和AES_DECRYPT() ...

  6. C++中的static成员

    C++中的static 成员永远是我心中的痛,记了好多次了,但是今天在项目中依然忘记了,今天写下来,方便以后不用再去Baidu.google搜索了. 在头文件中声明静态成员 static int i; ...

  7. next数组

    首先看看next数组值的求解方法例如: 模式串 a b a a b c a c next值 0 1 1 2 2 3 1 2               next数组的求解方法是:第一位的next值为0 ...

  8. 关于看似简单的eclipse中tomcat小猫图标消失的问题解决

    首先,这个问题出现在我新安装的虚拟机中,自己准备重新搭一套开发环境用于学习. 所以,出于好奇,自己从官网上把eclipse的最新版neo下下来尝尝鲜,刚安装好后发现与之前用的旧版基本相同,于是把相应的 ...

  9. Swift中对计算属性的理解和对之前的补充

    这个功能的重点作用应该是在计算上. 对于一般的属性,要么直接存一个,要么直接读一个,计算属性则可以根据所设置内容,进行一些修改或计算之类的, 比如: import UIKit class sample ...

  10. C#多线程实践——锁和线程安全

    锁实现互斥的访问,用于确保在同一时刻只有一个线程可以进入特殊的代码片段,考虑下面的类: class ThreadUnsafe { static int val1, val2; static void ...