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>

using namespace std;
const int N=2005;

inline int rd(){
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) f=ch=='-'?0:1,ch=getchar();
    while(isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
    return f?x:-x;
}

int n,Maxp,w,f[N][N],AP[N],BP[N],AS[N],BS[N];
int Q[N],head,tail;

int main(){
    memset(f,-0x3f,sizeof(f));
    n=rd(),Maxp=rd(),w=rd(); f[0][0]=0;
    for(int i=1;i<=n;i++)
        AP[i]=rd(),BP[i]=rd(),AS[i]=rd(),BS[i]=rd();
    for(int i=1;i<=n;i++){
        head=1; tail=0; f[i][0]=f[i-1][0];
        int Max=max(0,i-w-1);
        for(int j=1;j<=Maxp;j++){
            f[i][j]=f[i-1][j];
            if(j-Q[head]>AS[i]) head++;
            while(head<=tail && f[Max][j-1]-AP[i]>f[Max][Q[tail]]-AP[i]*(j-Q[tail])) tail--;
            Q[++tail]=j-1; f[i][j]=max(f[i][j],f[Max][Q[head]]-AP[i]*(j-Q[head]));
//          for(int k=1;k<=AS[i];k++){
//              if(k>j) break;
//              f[i][j]=max(f[i][j],f[max(0,i-w-1)][j-k]-AP[i]*k);
//          }
//          for(int k=1;k<=BS[i];k++){
//              if(j+k>Maxp) break;
//              f[i][j]=max(f[i][j],f[max(0,i-w-1)][j+k]+BP[i]*k);
//          }
        }
        head=1; tail=0;
        for(int j=Maxp-1;j>=0;j--){
            if(Q[head]-j>BS[i]) head++;
            while(head<=tail && f[Max][j+1]+BP[i]>f[Max][Q[tail]]+BP[i]*(Q[tail]-j)) tail--;
            Q[++tail]=j+1; f[i][j]=max(f[i][j],f[Max][Q[head]]+BP[i]*(Q[head]-j));
        }
    }
    /*
    for(int i=1;i<=n;i++)
        for(int j=0;j<=Maxp;j++)
            printf("f[%d][%d]=%d\n",i,j,f[i][j]);
    */
    printf("%d\n",f[n][0]);
    return 0;
}

原文地址:https://www.cnblogs.com/sdfzsyq/p/10560371.html

时间: 2025-01-13 12:54:43

LUOGU P2569 [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

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

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

单调队列定义: 其实单调队列就是一种队列内的元素有单调性的队列,因为其单调性所以经常会被用来维护区间最值或者降低DP的维数已达到降维来减少空间及时间的目的. 单调队列的一般应用: 1.维护区间最值 2.优化DP 例题引入: https://www.luogu.org/problemnew/show/P1440 一个含有n项的数列(n<=2000000),求出每一项前的m个数到它这个区间内的最小值.若前面的数不足m项则从第1个数开始,若前面没有数则输出0. 例题解答: 首先看到题目可以很快想到O(

部分单调队列优化 DP 题目解析

这里专门放一些单调队列优化 DP 的题目,并加上简要解析. Luogu P1725 琪露诺 易得转移方程为 $$f_i=\max_{j\,=\,\max(i-R,\;0)}^{i-L}f{_ j}+a_i\;(L \le i \le n)$$ 那么,其中 $\max$ 部分可以看成一段区间的最大值,用单调队列维护. 然后答案是 $$\max_{i\,=\,n-r+1}^{n} f_i$$ 时间复杂度 $O(n)$. 部分单调队列优化 DP 题目解析 原文地址:https://www.cnblog

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