zoukankan      html  css  js  c++  java
  • [SCOI2010]股票交易

     [SCOI2010]股票交易

    推荐的相关题目显示

    题目描述

    最近 lxhgww 又迷上了投资股票,通过一段时间的观察和学习,他总结出了股票行情的一些规律。

    通过一段时间的观察,lxhgww 预测到了未来 T 天内某只股票的走势,第 i 天的股票买入价为每股 APi,第 i 天的股票卖出价为每股 BPi(数据保证对于每个 i,都有 APiBPi),但是每天不能无限制地交易,于是股票交易所规定第 i 天的一次买入至多只能购买 ASi 股,一次卖出至多只能卖出 BSi 股。

    另外,股票交易所还制定了两个规定。为了避免大家疯狂交易,股票交易所规定在两次交易(某一天的买入或者卖出均算是一次交易)之间,至少要间隔 W 天,也就是说如果在第 i 天发生了交易,那么从第 i+1 天到第 i+W天,均不能发生交易。同时,为了避免垄断,股票交易所还规定在任何时间,

    一个人的手里的股票数不能超过MaxP。

    在第 1 天之前,lxhgww 手里有一大笔钱(可以认为钱的数目无限),但是没有任何股票,当然,T 天以后,lxhgww 想要赚到最多的钱,聪明的程序员们,你们能帮助他吗?

    输入输出格式

    输入格式:

    输入数据第一行包括 3 个整数,分别是 T,MaxP,W。

    接下来 T 行,第 i 行代表第 i1 天的股票走势,每行 4 个整数,分别表示 APi, BPi, ASi, BSi

    输出格式:

    输出数据为一行,包括 1 个数字,表示 lxhgww 能赚到的最多的钱数。

    输入输出样例

    输入样例#1: 
    5 2 0
    2 1 1 1
    2 1 1 1
    3 2 1 1
    4 3 1 1
    5 4 1 1
    
    输出样例#1: 
    3
    /*
    思路:
    对于我这样的蒟蒻来说是一道难题
    首先我们努力的列出一个DP式子
    dp[i][j]表示第i天持有j支股票
    那么我们便有四个决策
    首先如果持有股量不超当日上界的情况直接购入(其实这种决策被第三种决策完全包括,反正你加上了也不影响正确性)
    第二,我们不买也不卖,dp[i][j]=dp[i-1][j];
    第三,我们买入x支股(x<=as[i]) dp[i][j]=max(dp[i][j],dp[i-m-1][j-y])(1<=y<=min(j,as[i])) 
    第四,我们出手x支股,与上种决策类似
    这样的时间复杂度是O(TMaxPW) 期望50pts
    然后,可以发现dp[i-m-1][j-y]的j-y为单调上升,这样我们可以用单调队列维护一下
    然后,时间复杂度变成O(TMAXP)
    应该就可以通过除了COJ以外一切测评机了 
    */ 
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<time.h>
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    deque<pair<int,int> > Q,P;
    int ap[2005],bp[2050],as[2020],bs[2050],dp[2050][2050],n,m,t;
    int main(){
    	scanf("%d%d%d",&n,&t,&m);
    	m++;
    	rep(i,1,n) scanf("%d%d%d%d",&ap[i],&bp[i],&as[i],&bs[i]);
    	rep(i,1,t) dp[0][i]=-99999999;
    	rep(i,1,n){
    		if(i<=m){
    			rep(j,0,t){
    				dp[i][j]=dp[i-1][j];
    				if(j<=as[i] && dp[i][j]<-j*ap[i]) dp[i][j]=-j*ap[i];
    				//printf("dp[%d][%d]=%d
    ",i,j,dp[i][j]);
    			}
    			continue;
    		}
    		while(!Q.empty()) Q.pop_back();
    		while(!P.empty()) P.pop_back();
    		rep(j,1,min(t,bs[i])){
    			while(!Q.empty() && Q.back().second<=dp[i-m][j]+j*bp[i]) Q.pop_back();
                Q.push_back(make_pair(j,dp[i-m][j]+j*bp[i]));
    		}
    		rep(j,0,t){
    			dp[i][j]=dp[i-1][j];
    			if(j<=as[i] && dp[i][j]<=-j*ap[i]) dp[i][j]=-j*ap[i];
    			if(!Q.empty() && !P.empty()) dp[i][j]=max(dp[i][j],max(Q.front().second-j*bp[i],P.front().second-j*ap[i]));
    			else if(!Q.empty()) dp[i][j]=max(dp[i][j],Q.front().second-j*bp[i]);
    			else if(!P.empty()) dp[i][j]=max(dp[i][j],P.front().second-j*ap[i]);
    			while(!Q.empty() && Q.front().first==j+1) Q.pop_front();
    			while(!P.empty() && P.front().first+as[i]<j+1) P.pop_front();
    			while(!Q.empty() && j+bs[i]+1<=t && Q.back().second<=dp[i-m][j+bs[i]+1]+bp[i]*(j+bs[i]+1)) Q.pop_back();
    			while(!P.empty() && P.back().second<=dp[i-m][j]+ap[i]*j) P.pop_back();
    			P.push_back(make_pair(j,dp[i-m][j]+ap[i]*j));
    			if(j+bs[i]+1<=t) Q.push_back(make_pair(j+bs[i]+1,dp[i-m][j+bs[i]+1]+bp[i]*(j+bs[i]+1)));
    		}
    	}
    	printf("%d",dp[n][0]);
    	return 0;
    }
    

      

  • 相关阅读:
    初学微信小程序 TodoList
    设计一个基于svg的涂鸦组件(一)
    基于51单片机的12864驱动
    java 使用xom对象数据序列化为xml、反序列化、Preferences相关操作小案例
    ios UIWebView 播放优酷土豆视频
    VMware Player 使用错误集锦
    Django 使用UEditor
    Entity Framework底层操作封装V2版本号(3)
    cocos2dx笔记1:概述
    oracle10g精简版安装步骤
  • 原文地址:https://www.cnblogs.com/handsome-zlk/p/10049189.html
Copyright © 2011-2022 走看看