• P2569 [SCOI2010]股票交易 dp 单调队列优化


    LINK:股票交易

    题目确实不算难 但是坑点挺多 关于初值的处理问题我就wa了两次。

    所以来谢罪。

    由于在手中的邮票的数量存在限制 且每次买入卖出也有限制。

    必然要多开一维来存每天的邮票数量。

    那么容易想到(f_{i,j})表示到了第(i)天有(j)张邮票的最大赚钱值。

    每次需要间隔W天进行操作 W变成W+1 那么在第i天能够转移的是 (0~i-W)这个区间了。

    枚举前面哪一天 买入卖出k张邮票 就可以得到(n^2m^2)的做法.

    容易想到我们只需要(i-W)这个地方的值即可 强制要求 (i,j,k,i<j)(f_{i,k}leq f_{j,k})显然这样做不会更差.

    复杂度为(nm^2)枚举决策k的时候容易想到单调队列优化 那么复杂度为(ncdot m)

    关于初值的问题 每次对于(0-L)先进行强制赋值然后和前一天比max 这点容易想当然的写错...

    code
    //#include<bitsstdc++.h>
    #include<iostream>
    #include<iomanip>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<ctime>
    #include<cmath>
    #include<cctype>
    #include<cstdlib>
    #include<queue>
    #include<deque>
    #include<stack>
    #include<vector>
    #include<algorithm>
    #include<utility>
    #include<bitset>
    #include<set>
    #include<map>
    #define ll long long
    #define db double
    #define INF 10000000000000000ll
    #define ldb long double
    #define pb push_back
    #define put_(x) printf("%d ",x);
    #define get(x) x=read()
    #define gt(x) scanf("%d",&x)
    #define gi(x) scanf("%lf",&x)
    #define put(x) printf("%d
    ",x)
    #define putl(x) printf("%lld
    ",x)
    #define gc(a) scanf("%s",a+1)
    #define rep(p,n,i) for(RE int i=p;i<=n;++i)
    #define go(x) for(int i=lin[x],tn=ver[i];i;tn=ver[i=nex[i]])
    #define fep(n,p,i) for(RE int i=n;i>=p;--i)
    #define vep(p,n,i) for(RE int i=p;i<n;++i)
    #define pii pair<int,int>
    #define mk make_pair
    #define RE register
    #define P 1000000007
    #define gf(x) scanf("%lf",&x)
    #define pf(x) ((x)*(x))
    #define uint unsigned long long
    #define ui unsigned
    #define EPS 1e-4
    #define sq sqrt
    #define S second
    #define F first
    #define mod 1000000007
    using namespace std;
    char buf[1<<15],*fs,*ft;
    inline char getc()
    {
        return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;
    }
    inline int read()
    {
        RE int x=0,f=1;RE char ch=getc();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getc();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getc();}
        return x*f;
    }
    const int MAXN=2010;
    int n,maxx,W;
    int f[MAXN][MAXN];
    int q[MAXN],t,h;
    int main()
    {
    	//freopen("1.in","r",stdin);
    	get(n);get(maxx);get(W)+1;
    	memset(f,0xcf,sizeof(f));
    	f[0][0]=0;
    	rep(1,n,i)
    	{
    		int get(l),get(r),get(L),get(R);
    		if(i<W)
    		{
    			f[i][0]=0;
    			rep(1,L,j)f[i][j]=max(f[i-1][j],-l*j);
    			rep(L+1,maxx,j)f[i][j]=max(f[i][j],f[i-1][j]);
    		}
    		else
    		{
    			//考虑买入.
    			f[i][0]=f[i-1][0];
    			q[t=h=1]=0;
    			rep(1,maxx,j)
    			{
    				while(h<t&&j-q[h]>L)++h;
    				f[i][j]=max(f[i-1][j],f[i-W][q[h]]-l*(j-q[h]));
    				while(h<=t&&f[i-W][j]+j*l>=f[i-W][q[t]]+q[t]*l)--t;
    				q[++t]=j;
    			}
    			//考虑卖出.
    			q[t=h=1]=maxx;
    			fep(maxx-1,0,j)
    			{
    				while(h<t&&q[h]-j>R)++h;
    				f[i][j]=max(f[i][j],f[i-W][q[h]]+(q[h]-j)*r);
    				while(h<=t&&f[i-W][j]+j*r>=f[i-W][q[t]]+q[t]*r)--t;
    				q[++t]=j;
    			}
    		}
    	}
    	put(f[n][0]);
    	return 0;
    }
    
  • 相关阅读:
    P3_C17:设计对象的原则
    【c++编程习惯】关于我自己
    淘宝退货业务 活动图
    UML绘图要点
    P2_C4-7:初始阶段
    P3_C8-11:细化阶段-基础迭代
    P3_C14-16:面向对象设计
    P3_C12-13:逻辑架构和包图
    P1_C1-3:系统分析与设计概要
    Chapter11 线程
  • 原文地址:https://www.cnblogs.com/chdy/p/13299542.html
Copyright © 2020-2023  润新知