• hdu-3401-Trade-单调队列优化的DP


    单调队列入门题。。。

    dp[i][j]:第i天。手中拥有j个股票时,获得的最大利润。

    若第i天不买不卖:dp[i][j]=max(dp[i][j],dp[i-1][j]);

    若第i天买            :dp[i][j]=max(dp[i][j],dp[i-w-1][k]-(j-k)*ap[i]);

    若第i天卖            :dp[i][j]=max(dp[i][j],dp[i-w-1][k]+(k-j)*bp[i]);

    若仅仅考虑买的情况:
    dp[i][j]=dp[i-w-1][k]+ap[i]*k-j*ap[i];

    非常明显。能够用单调队列优化dp[i-w-1][k]+ap[i]*k。

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<iostream>
    #include<queue>
    using namespace std;
    //#define INF ((1<<30)-1)
    #define INF 0xfffff
    #define maxn 2200
    #define LL long long
    #define MOD 1000000009
    int dp[2200][2200];
    struct list
    {
        int val;
        int x;
    } p[5001],q;
    int ap[maxn],bp[maxn],as[maxn],bs[maxn];
    int main()
    {
        int Ts;
        int n,m,w,i,j;
        scanf("%d",&Ts);
        while(Ts--)
        {
            scanf("%d%d%d",&n,&m,&w);
            for(i=0; i<=n; i++)
                for(j=0; j<=m; j++)dp[i][j]=-INF;
            int head,tail;
            for(i=1;i<=n;i++)scanf("%d%d%d%d",&ap[i],&bp[i],&as[i],&bs[i]);
            for(j=1;j<=w+1;j++)
                for(i=0;i<=min(as[j],m);i++)
                    dp[j][i]=-1*ap[j]*i;
            for(i=2; i<=n; i++)
            {
                for(j=0;j<=m;j++)dp[i][j]=max(dp[i-1][j],dp[i][j]);
                if(i<=w+1)continue;
                head=1;
                tail=0;
                for(j=0; j<=m; j++)
                {
                    q.x=j;
                    q.val=dp[i-w-1][j]+ap[i]*j;
                    while(tail>=head&&q.val>p[tail].val)tail--;
                    p[++tail]=q;
                    while(tail>=head&&p[head].x<j-as[i])head++;
                    if(head<=tail)dp[i][j]=max(dp[i][j],p[head].val-ap[i]*j);
                }
                head=1;
                tail=0;
                for(j=m;j>=0;j--)
                {
                    q.x=j;
                    q.val=dp[i-w-1][j]+bp[i]*j;
                    while(tail>=head&&q.val>p[tail].val)tail--;
                    p[++tail]=q;
                    while(tail>=head&&p[head].x>j+bs[i])head++;
                    if(head<=tail)dp[i][j]=max(dp[i][j],p[head].val-bp[i]*j);
                }
            }
            int maxx=0;
            for(i=0;i<=m;i++)maxx=max(maxx,dp[n][i]);
            printf("%d
    ",maxx);
        }
        return 0;
    
    }


  • 相关阅读:
    python管理包(模块和包的应用)
    简单运行 Jupyter Notebook
    Linux出现“FirewallD is not running”解决办法
    Mindjet MindManager2020切换中文界面的教程
    idea 快捷键汇总
    南怀瑾经典语录
    CentOS 7 安装SonarQube 8.3版本
    Jenkins插件开发完全示例
    Jenkins在Pod中实现Docker in Docker并用kubectl进行部署
    Jenkins的kubernetes-plugin使用方法
  • 原文地址:https://www.cnblogs.com/wzjhoutai/p/6977902.html
Copyright © 2020-2023  润新知