【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][k]+k*e[i).ap-j*e[i].ap。令a[i-W-1][k]=f[i-W-1][k]+k*e[i].ap(事实上完全不用a这个数组,用单调队列),则f[i][j]=max(a[i-W-1][k]) - j*e[i].ap。枚举要从0到mxa

3.卖出,原理同上,枚举要从mxa到0

最后的f[n][0]即为答案(现实意义为第n天此时手里没有任何股票时的最大收益)。

具体实现看代码:

#include<cstdio>
#include<cstring>
#include<iostream>
const int M=2010,inf=0x3f3f3f3f;
using namespace std;
struct point
{
    int ap,bp,as,bs;
}e[M];
struct node{int pos,k;}a[M];
int f[M][M],head,tail;
int main()
{
    int n,mxa,w;
    bool ok;
    memset(f,-inf,sizeof(f));
    scanf("%d %d %d",&n,&mxa,&w);
    for(int i=1;i<=n;i++)scanf("%d %d %d %d",&e[i].ap,&e[i].bp,&e[i].as,&e[i].bs);
    for(int i=1;i<=w+1;i++)
        for(int j=1;j<=e[i].as;j++)
        f[i][j]=-e[i].ap*j;
    f[0][0]=0;
    for(int i=1;i<=n;i++)
    {
        for(int j=0;j<=mxa;j++)f[i][j]=max(f[i][j],f[i-1][j]);
        if(i<=w+1)continue;
        int now=i-w-1;
        head=tail=0;
        for(int j=0;j<=mxa;j++)
        {
            ok=true;
            int now1=f[now][j]+j*e[i].ap;
            while(head<tail&&a[tail-1].k<now1)tail--;
            a[tail].k=now1;a[tail++].pos=j;
            while(a[head].pos+e[i].as<j){if(head==tail){ok=false;break;}head++;}
            if(ok)f[i][j]=max(f[i][j],a[head].k-j*e[i].ap);
        }
        head=tail=0;
        for(int j=mxa;j>=0;j--)
        {
            ok=true;
            int now1=f[now][j]+j*e[i].bp;
            while(head<tail&&a[tail-1].k<now1)tail--;
            a[tail].k=now1;a[tail++].pos=j;
            while(a[head].pos-e[i].bs>j){if(head==tail){ok=false;break;}head++;}
            if(ok)f[i][j]=max(f[i][j],a[head].k-j*e[i].bp);
        }
    }
    printf("%d",f[n][0]);
    return 0;
}

bzoj1855

注意一点就是hdu3401这道题有多组数据,记得改一下再交啊(不然就像我一样WA了……)

#include<cstdio>
#include<cstring>
#include<iostream>
const int M=2010,inf=0x3f3f3f3f;
using namespace std;
struct point
{
    int ap,bp,as,bs;
}e[M];
struct node{int pos,k;}a[M];
int f[M][M],head,tail;
int main()
{
    int n,mxa,w,tt;
    bool ok;
    scanf("%d",&tt);
    while(tt--)
    {
        memset(f,-inf,sizeof(f));
        scanf("%d %d %d",&n,&mxa,&w);
        for(int i=1;i<=n;i++)scanf("%d %d %d %d",&e[i].ap,&e[i].bp,&e[i].as,&e[i].bs);
        for(int i=1;i<=w+1;i++)
            for(int j=1;j<=e[i].as;j++)
            f[i][j]=-e[i].ap*j;
        f[0][0]=0;
        for(int i=1;i<=n;i++)
        {
            for(int j=0;j<=mxa;j++)f[i][j]=max(f[i][j],f[i-1][j]);
            if(i<=w+1)continue;
            int now=i-w-1;
            head=tail=0;
            for(int j=0;j<=mxa;j++)
            {
                ok=true;
                int now1=f[now][j]+j*e[i].ap;
                while(head<tail&&a[tail-1].k<now1)tail--;
                a[tail].k=now1;a[tail++].pos=j;
                while(a[head].pos+e[i].as<j){if(head==tail){ok=false;break;}head++;}
                if(ok)f[i][j]=max(f[i][j],a[head].k-j*e[i].ap);
            }
            head=tail=0;
            for(int j=mxa;j>=0;j--)
            {
                ok=true;
                int now1=f[now][j]+j*e[i].bp;
                while(head<tail&&a[tail-1].k<now1)tail--;
                a[tail].k=now1;a[tail++].pos=j;
                while(a[head].pos-e[i].bs>j){if(head==tail){ok=false;break;}head++;}
                if(ok)f[i][j]=max(f[i][j],a[head].k-j*e[i].bp);
            }
        }
        printf("%d\n",f[n][0]);
    }
    return 0;
}

hdu3401

时间: 2024-10-11 06:47:37

【bzoj1855||hdu3401】股票交易——单调队列优化dp的相关文章

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

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>=

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]+

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

hdu3401 Trade(单调队列优化dp)

Trade Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4734    Accepted Submission(s): 1587 Problem Description Recently, lxhgww is addicted to stock, he finds some regular patterns after a few d

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[

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

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