• [SCOI2010]股票交易


    XX.[SCOI2010]股票交易

    这题状态很好想:设\(f[i][j]\)表示:第\(i\)天,持有\(j\)支股票,的最大收益。

    然后我就脑残了,想了个\(O(n^2m^2)\)的弱智初始DP,然后就WA掉惹。

    实际上转移也挺简单的。设第\(i\)天买股票花\(a_i\)元,卖股票花\(b_i\)元,可以买\(A_i\)次,卖\(B_i\)次。

    1. 从起始状态转移。即,如果有\(j\leq A_i\)\(f[i][j]=-j*a_i\)

    2. 这一时刻不买。即,\(f[i][j]=f[i-1][j]\)

    3. \(i-w-1\)时刻买。即,\(f[i][j]=\max\{f[i-w-1][l]+\text{买或卖的费用}\}\)

    然后1和2都是\(nm\)的;3套上单调队列也是\(nm\)的;总复杂度\(O(nm)\)

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    int n,m,w,a[2010],b[2010],A[2010],B[2010];
    ll f[2010][2010];
    deque<int>q;
    int main(){
    	scanf("%d%d%d",&n,&m,&w),w++,memset(f,0x80,sizeof(f));
    	for(int i=1;i<=n;i++)scanf("%d%d%d%d",&a[i],&b[i],&A[i],&B[i]);
    	for(int i=1;i<=n;i++){
    		for(int j=0;j<=m;j++){
    			if(j<=A[i])f[i][j]=-j*a[i];
    			f[i][j]=max(f[i][j],f[i-1][j]);	
    		}
    		if(i-w<=0)continue;
    		int k=i-w;
    		q.clear();
    		for(int j=0;j<=m;j++){
    			while(!q.empty()&&j-q.front()>A[i])q.pop_front();
    			while(!q.empty()&&f[k][q.back()]-(j-q.back())*a[i]<=f[k][j])q.pop_back();
    			q.push_back(j);
    			f[i][j]=max(f[i][j],f[k][q.front()]-(j-q.front())*a[i]);
    		}
    		q.clear();
    		for(int j=m;j>=0;j--){
    			while(!q.empty()&&q.front()-j>B[i])q.pop_front();
    			while(!q.empty()&&f[k][q.back()]+(q.back()-j)*b[i]<=f[k][j])q.pop_back();
    			q.push_back(j);
    			f[i][j]=max(f[i][j],f[k][q.front()]+(q.front()-j)*b[i]);
    		}
    	}
    //	for(int i=1;i<=n;i++){for(int j=0;j<=m;j++)printf("%d ",f[i][j]);puts("");}
    	printf("%lld\n",f[n][0]);
    	return 0;
    }
    

  • 相关阅读:
    功夫世界外挂发布测试
    k8s和docker日常使用命令
    notepad添加JSON插件菜单栏不显示的问题
    k8s中的网络
    MySQL日志系统之redo log和bin log
    OCR文字识别开源方案本地部署 hello
    .NET Core WebAPI post参数传递时后端的接收方式
    sqlserver 数据库自动备份
    对EF中5种实体状态System.Data.EntityState的一点理解
    造成跨域的原因和解决方法
  • 原文地址:https://www.cnblogs.com/Troverld/p/14596941.html
Copyright © 2020-2023  润新知