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 }