hdu 3401(单调队列优化dp)
2016-08-17 21:51
489 查看
注意:这题题意是有操作的天数相隔要大于w
然后列出状态转移方程就可以发现,可以用优点队列优化啦。
构造状态dp[i][j]表示第i 天拥有 j只股票的时候,赚了多少钱
状态转移有:
1、从前一天不买不卖:
dp[i][j]=max(dp[i-1][j],dp[i][j])
2、从前i-W-1天买进一些股:
dp[i][j]=max(dp[i-W-1][k]-(j-k)*AP[i],dp[i][j])
3、从i-W-1天卖掉一些股:
dp[i][j]=max(dp[i-W-1][k]+(k-j)*BP[i],dp[i][j])
然后列出状态转移方程就可以发现,可以用优点队列优化啦。
构造状态dp[i][j]表示第i 天拥有 j只股票的时候,赚了多少钱
状态转移有:
1、从前一天不买不卖:
dp[i][j]=max(dp[i-1][j],dp[i][j])
2、从前i-W-1天买进一些股:
dp[i][j]=max(dp[i-W-1][k]-(j-k)*AP[i],dp[i][j])
3、从i-W-1天卖掉一些股:
dp[i][j]=max(dp[i-W-1][k]+(k-j)*BP[i],dp[i][j])
// // main.cpp // hdu3401 // // Created by New_Life on 16/8/16. // Copyright © 2016年 chenhuan001. All rights reserved. // #include <iostream> #include <stdio.h> #include <algorithm> #include <queue> #include <string.h> #include <string> using namespace std; #define N 2020 #define INF 100000000 /******************_单调队列模板_******************/ //基于单调队列功能的单一性:以limit为序查找在一定范围内的极值。 //复杂度:O(n) //用法: 创建的时候调用.init() // 插入队列:.push( Q_Node( KEY,LIMIT ) ); // 设置limit值:.setlimit( LIMIT ); // 查询<limit值的最大元素: Q_Node qn; q2.top(qn); // 再查询前需要设置limit值,如果队列为空返回false,否则将最大元素存入qn中并返回true struct Q_Node { int key,limit;//用来比较大小的key和控制存在时间的limit Q_Node(){} Q_Node(int _key,int _limit){ key=_key,limit=_limit; } }; struct Q_Que { Q_Node Q ; int qf,qd; int limit;// <limit 的元素将被弹出 void init() { qf = qd = 0;//将队列内元素清空 } void push(Q_Node newnode) {//默认入队是当前limit最大的 while (qf>qd && Q[qf-1].key < newnode.key) qf--; Q[qf++] = newnode; } void setlimit(int _limit) { limit = _limit; } /* 取出队列中>=limit且key最大的元素。 */ bool top(Q_Node &rt) { while(qf>qd && Q[qd].limit < limit) qd++; if(qf==qd) return false; rt = Q[qd]; return true; } }q1,q2; int dp ; int ap ,bp ,as ,bs ; int main(int argc, const char * argv[]) { int T; cin>>T; while(T--) { int t,mxp,w; cin>>t>>mxp>>w; for(int i=1;i<=t;i++) scanf("%d%d%d%d",ap+i,bp+i,as+i,bs+i); for(int i=0;i<=t;i++) for(int j=0;j<=mxp;j++) dp[i][j] = -INF; for(int i=1;i<=w+1;i++) for(int j=0;j<=as[i];j++) dp[i][j] = -j*ap[i]; dp[0][0] = 0; for(int i=1;i<=t;i++) { q1.init(); q2.init(); int sum1=0,sum2=0; for(int j=0;j<=mxp;j++) { dp[i][j] = max(dp[i][j],dp[i-1][j]);//啥也没做 } if(i <= w+1) continue; for(int j=0;j<=mxp;j++) { q1.push( Q_Node(dp[i-w-1][j]-sum1,j) ); q1.setlimit(j-as[i]); Q_Node qn; if(q1.top(qn)) { dp[i][j] = max(dp[i][j],qn.key+sum1); } sum1 -= ap[i]; } for(int j=mxp;j>=0;j--){ q2.push(Q_Node(dp[i-w-1][j]-sum2, -j)); q2.setlimit(-j-bs[i]); Q_Node qn; if(q2.top(qn)) dp[i][j] = max(dp[i][j],qn.key+sum2); sum2 += bp[i]; } } int ans = 0; for(int i=1;i<=t;i++) for(int j=0;j<=mxp;j++) ans= max(ans,dp[i][j]); cout<<ans<<endl; } return 0; } /* 20 5 2 0 2 1 1 1 2 1 1 1 3 2 1 1 4 3 1 1 5 4 1 1 5 3 0 2 1 2 2 2 1 12 1 3 2 2 1 4 3 3 2 5 4 1 2 5 2 3 2 1 3 2 1 1 12 1 3 2 2 2 4 3 3 3 5 4 1 2 5 3 3 2 1 3 2 1 1 12 1 3 4 2 2 1 3 3 3 1 3 3 5 5 10 0 2 1 3 2 1 1 12 1 3 4 2 2 1 3 3 3 1 3 3 5 5 10 0 2 1 3 2 1 1 12 0 3 4 4 2 1 3 0 3 1 3 0 5 4 1 1 1 1 1 1 1 1 1 1 1 3 1 1 1 3 1 1 10 4 3 1 3 1 1 1 5 1 1 1 10 6 1 1 10 6 1 1 */
相关文章推荐
- hdu-3401-Trade-单调队列优化的DP
- hdu 3401 Trade(单调队列优化DP)
- HDU-3401:Trade(dp+单调队列优化)
- HDU-3401 Trade 单调队列优化DP
- hdu 3401 Trade 单调队列优化dp
- HDU 3401 Trade 单调队列优化DP
- 【单调队列优化dp】HDU 3401 Trade
- HDU 3401 Trade(单调队列优化DP)【模板】
- bzoj1855: [Scoi2010]股票交易 单调队列优化dp ||HDU 3401
- HDU 3401 Trade (单调队列优化DP)
- hdu 3401 Trade(单调队列优化dp)
- hdu 3401 单调队列优化DP
- 股票交易 【SCOI 2010】HDU 3401 (单调队列优化DP入门)
- HDU 3401 Trade (单调队列优化DP)
- hdu 3401 单调队列优化+dp
- HDU 3401 Trade(用单调队列优化DP)
- hdu 3401 单调队列优化DP
- 【HDU 3401 Trade】 单调队列优化dp
- hdu 3401(单调队列优化dp)
- HDU - 3401 单调队列优化DP