BZOJ 1855 [Scoi2010]股票交易 单调队列优化DP

题意:链接

方法:单调队列优化DP

解析:噢又是一道情况很多的题,然而三种更新我又落下一种导致样例不过,后来看题解才恍然- -最SB的一种更新居然忘了。

状态好想f[i][j]代表前i天有j双袜子时的最大利润。

三种更新:

第一种:f[i][j]=max(f[i][j],f[i?1][j]);(然而我忘了这一种)

第二种:买入f[i][j]=max(f[i][j],f[i?w?1][k]?(j?k)?a[i].ap)(k>=j?a[i].as);

第三种:卖出f[i][j]=max(f[i][j],f[i?w?1][k]+(k?j)?a[i].bp)(k<=max(maxp,j+a[i].bs))

然后我们观察式子,第一种更新O(1)完成,第二和第三的时候如果枚举k的话复杂度承受不了,所以考虑怎么优化,显而易见第二三种是线性的,所以考虑到队列可不可行?于是整理表达式,发现可行,则按照f[i-w-1][k]+k*a[i].ap以及f[i-w-1][k]+k*a[i].bp维护递减就可以。

代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 2010
using namespace std;
int t,maxp,w;
int f[N][N];
int q[N];
struct node
{
    int ap,bp,as,bs;
}a[N];
int main()
{
    scanf("%d%d%d",&t,&maxp,&w);
    for(int i=1;i<=t;i++)
    {
        scanf("%d%d%d%d",&a[i].ap,&a[i].bp,&a[i].as,&a[i].bs);
    }
    memset(f,-0x3f,sizeof(f));
    for(int i=1;i<=t;i++)
    {
        for(int j=0;j<=a[i].as;j++)f[i][j]=-a[i].ap*j;
        for(int j=0;j<=maxp;j++)f[i][j]=max(f[i][j],f[i-1][j]);
        if(i-w-1>=0)
        {
            int head=0,tail=0;
            for(int j=0;j<=maxp;j++)
            {
                while(head<tail&&q[head]<j-a[i].as)head++;
                while(head<tail&&f[i-w-1][j]+j*a[i].ap>=f[i-w-1][q[tail-1]]+q[tail-1]*a[i].ap)tail--;
                q[tail++]=j;
                if(head<tail)f[i][j]=max(f[i][j],f[i-w-1][q[head]]-(j-q[head])*a[i].ap);
            }
            head=0,tail=0;
            for(int j=maxp;j>=0;j--)
            {
                while(head<tail&&q[head]>j+a[i].bs)head++;
                while(head<tail&&f[i-w-1][j]+j*a[i].bp>=f[i-w-1][q[tail-1]]+q[tail-1]*a[i].bp)tail--;
                q[tail++]=j;
                if(head<tail)f[i][j]=max(f[i][j],f[i-w-1][q[head]]+(q[head]-j)*a[i].bp);
            }
        }
    }
    int ans=0;
    for(int i=0;i<=maxp;i++)
    {
        ans=max(ans,f[t][i]);
    }
    printf("%d\n",ans);
}
时间: 2024-12-14 09:19:50

BZOJ 1855 [Scoi2010]股票交易 单调队列优化DP的相关文章

1855: [Scoi2010]股票交易[单调队列优化DP]

1855: [Scoi2010]股票交易 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1083  Solved: 519[Submit][Status][Discuss] Description 最近lxhgww又迷上了投资股票,通过一段时间的观察和学习,他总结出了股票行情的一些规律. 通过一段时间的观察,lxhgww预测到了未来T天内某只股票的走势,第i天的股票买入价为每股APi,第i天的股票卖出价为每股BPi(数据保证对于每个i,都有APi>=

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-1][k]+k*Ap[i]的单调性即可 1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 const int maxn = 2010; 6 int

LUOGU P2569 [SCOI2010]股票交易(单调队列优化dp)

传送门 解题思路 不难想一个\(O(n^3)\)的\(dp\),设\(f_{i,j}\)表示第\(i\)天,手上有\(j\)股的最大收益,因为这个\(dp\)具有单调性,所以\(f_i\)可以贪心的直接从\(f_{i-w-1}\)那一层转移来,转移时枚举一下当前买卖多少.考虑优化,发现每次其实就是一个区间取\(max\),是由\(AS\)和\(BS\)所限制的区间,所以单调队列优化就好了,一个正着做一个倒着做,时间复杂度\(O(n^2)\) 代码 #include<bits/stdc++.h>

AcWing - 332 - 股票交易 = 单调队列优化dp

https://www.acwing.com/problem/content/334/ 第一次写单调队列优化的dp,首先朴素的做法不难想到,就是复杂度 \(O(n^3)\) ,然后考虑优化. 每天都从 \(pre=max(0,i-w-1)\) 天转移过来就刚刚好了. 考虑每个k是怎么更新j的. 买入股票: \(dp[i][j]=max\{dp[pre][k]-(j-k)*AP_i\;|\;k \leq j\;and\;(j-k) \leq AS_i\}\) \(dp[i][j]=max\{dp[

【bzoj1855||hdu3401】股票交易——单调队列优化dp

代码基本是跟着yy dalao码的吧, 主要是要知道单调队列优化要怎么做, f[i][j]表示第i天手里有j股时的收益. 从第一天到第w+1天初始化为-e[i].ap*j(因为此时只能买不能卖),其余为-inf. 分三种情况: 1.不买不卖:即f[i][j]=max(f[i][j],f[i-1][j]); 2.买进: f[i][j]=max(f[i-W-1][k]-(j-k)*e[i].ap,f[i][j]).在这里j-e[i].as<k<=mxa,利用f[i][j]=max(f[i-W-1]

BZOJ 1855 股票交易(单调队列优化DP)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1855 题意:最近lxhgww又迷上了投资股票, 通过一段时间的观察和学习,他总结出了股票行情的一些规律. 通过一段时间的观察,lxhgww预测到了未来T天内某只股票的走势,第i天的股票买入价为每股APi,第i天的股票卖出价为每股BPi(数据保证对于每 个i,都有APi>=BPi),但是每天不能无限制地交易,于是股票交易所规定第i天的一次买入至多只能购买ASi股,一次卖出至多只能卖出BS

【笔记篇】单调队列优化dp学习笔记&amp;&amp;luogu2569_bzoj1855股票交♂易

DP颂 DP之神 圣洁美丽 算法光芒照大地 我们怀着 崇高敬意 跪倒在DP神殿里 你的复杂 能让蒟蒻 试图入门却放弃 在你光辉 照耀下面 AC真心不容易 dp大概是最经久不衰 亘古不化的算法了吧. 而且有各种各样的类型 优化之类的. 一直dp都不怎么好. 而且也不太知道应该怎么提高. 基本见到不认识的dp方程就不大会推(但我会打表啊= = 所以dp还是很有的学的~ 正好最近刚刚肝了计算几何, 所以就顺带搞一下斜率优化dp一类的... 单调队列优化dp 单调队列大家都会吧? 不会的先出去学一下,

HDU 4122 Alice&#39;s mooncake shop 单调队列优化dp

Alice's mooncake shop Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=4122 Description The Mid-Autumn Festival, also known as the Moon Festival or Zhongqiu Festival is a popular harvest festival celebrated by Ch

Tyvj1305最大子序和(单调队列优化dp)

描述 输入一个长度为n的整数序列,从中找出一段不超过M的连续子序列,使得整个序列的和最大. 例如 1,-3,5,1,-2,3 当m=4时,S=5+1-2+3=7当m=2或m=3时,S=5+1=6 输入格式 第一行两个数n,m第二行有n个数,要求在n个数找到最大子序和 输出格式 一个数,数出他们的最大子序和 测试样例1 输入 6 4 1 -3 5 1 -2 3 输出 7 备注 数据范围:100%满足n,m<=300000 是不超过m,不是选m个!!!!! /* 单调队列优化dp 单调队列维护的是前