HDU-3401 Trade 单调队列优化DP

  题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3401

  DP方程容易想出来,f[i][j]表示第i天拥有j个股票的最优解,则:

    1、不买不卖,f[i][j]=Max{ f[i][j], f[i-1][j] }。

    2、买进,f[i][j]=Max{ f[i][j], f[pre][k] - (j-k)*ap[i] | j>=k }。

    3、卖出,f[i][j]=Max{ f[i][j], f[pre][k] +(k-j)*bp[i] | k>=j }。

  直接转移复杂度O(n^3),超时。考虑第二种情况,f[pre][k] - (j-k)*ap[i] = (f[pre][k]+k*ap[i])-j*ap[i],用单调队列维护这个值(f[pre][k]+k*ap[i])就可以了。情况3类似。

  1 //STATUS:C++_AC_375MS_16132KB
  2 #include <functional>
  3 #include <algorithm>
  4 #include <iostream>
  5 //#include <ext/rope>
  6 #include <fstream>
  7 #include <sstream>
  8 #include <iomanip>
  9 #include <numeric>
 10 #include <cstring>
 11 #include <cassert>
 12 #include <cstdio>
 13 #include <string>
 14 #include <vector>
 15 #include <bitset>
 16 #include <queue>
 17 #include <stack>
 18 #include <cmath>
 19 #include <ctime>
 20 #include <list>
 21 #include <set>
 22 #include <map>
 23 using namespace std;
 24 //#pragma comment(linker,"/STACK:102400000,102400000")
 25 //using namespace __gnu_cxx;
 26 //define
 27 #define pii pair<int,int>
 28 #define mem(a,b) memset(a,b,sizeof(a))
 29 #define lson l,mid,rt<<1
 30 #define rson mid+1,r,rt<<1|1
 31 #define PI acos(-1.0)
 32 //typedef
 33 typedef long long LL;
 34 typedef unsigned long long ULL;
 35 //const
 36 const int N=2010;
 37 const int INF=0x3f3f3f3f;
 38 const int MOD=1e+7,STA=8000010;
 39 const LL LNF=1LL<<60;
 40 const double EPS=1e-8;
 41 const double OO=1e15;
 42 const int dx[4]={-1,0,1,0};
 43 const int dy[4]={0,1,0,-1};
 44 const int day[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
 45 //Daily Use ...
 46 inline int sign(double x){return (x>EPS)-(x<-EPS);}
 47 template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;}
 48 template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}
 49 template<class T> inline T lcm(T a,T b,T d){return a/d*b;}
 50 template<class T> inline T Min(T a,T b){return a<b?a:b;}
 51 template<class T> inline T Max(T a,T b){return a>b?a:b;}
 52 template<class T> inline T Min(T a,T b,T c){return min(min(a, b),c);}
 53 template<class T> inline T Max(T a,T b,T c){return max(max(a, b),c);}
 54 template<class T> inline T Min(T a,T b,T c,T d){return min(min(a, b),min(c,d));}
 55 template<class T> inline T Max(T a,T b,T c,T d){return max(max(a, b),max(c,d));}
 56 //End
 57 int f[N][N],ap[N],bp[N],as[N],bs[N],q[N*2][2];
 58 int T,n,m,d;
 59 int main()
 60 {
 61  //   freopen("in.txt","r",stdin);
 62     int i,j,k,hig,ans,front,rear,p;
 63     scanf("%d",&T);
 64     while(T--)
 65     {
 66         scanf("%d%d%d",&n,&m,&d);
 67         for(i=1;i<=n;i++){
 68             scanf("%d%d%d%d",&ap[i],&bp[i],&as[i],&bs[i]);
 69         }
 70         mem(f,-INF);
 71         for(i=1;i<=d+1;i++){
 72             for(j=0;j<=as[i];j++)
 73                 f[i][j]=-j*ap[i];
 74         }
 75         for(i=1;i<=d+1;i++){
 76             for(j=0;j<=m;j++)
 77                 f[i][j]=max(f[i][j],f[i-1][j]);
 78         }
 79         for(i=d+2;i<=n;i++){
 80             p=i-d-1;
 81             for(j=0;j<=m;j++)f[i][j]=f[i-1][j];
 82             //
 83             front=rear=0;
 84             q[rear][0]=f[p][0];q[rear++][1]=0;
 85             for(j=1;j<=m;j++){
 86                 while(front<rear && q[front][1]<j-as[i])front++;
 87                 f[i][j]=max(f[i][j],q[front][0]-j*ap[i]);
 88                 while(front<rear && q[rear-1][0]<=f[p][j]+j*ap[i])rear--;
 89                 q[rear][0]=f[p][j]+j*ap[i];q[rear++][1]=j;
 90             }
 91             //
 92             front=rear=0;
 93             q[rear][0]=f[p][m]+m*bp[i];q[rear++][1]=m;
 94             for(j=m-1;j>=0;j--){
 95                 while(  front<rear && q[front][1]>j+bs[i])front++;
 96                 f[i][j]=max(f[i][j],q[front][0]-j*bp[i]);
 97                 while(front<rear && q[rear-1][0]<=f[p][j]+j*bp[i])rear--;
 98                 q[rear][0]=f[p][j]+j*bp[i];q[rear++][1]=j;
 99             }
100         }
101         ans=0;
102         for(i=0;i<=m;i++)ans=max(ans,f[n][i]);
103         printf("%d\n",ans);
104     }
105     return 0;
106 }

 

你可能感兴趣的:(HDU)