zoukankan      html  css  js  c++  java
  • 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;
    
    }


  • 相关阅读:
    计算机原理 3.4 补码一位乘法
    信号与系统 第二章(2.1)
    信号与系统(1.6、1.7)
    第17章 使用BIOS进行键盘输入和磁盘读写
    第16章 直接定址表
    聚类:主要聚类算法
    机器学习——输入空间、特征空间、输出空间
    机器学习——线性回归
    机器学习——梯度下降法
    深度学习——概率与信息论
  • 原文地址:https://www.cnblogs.com/wzjhoutai/p/6977902.html
Copyright © 2011-2022 走看看