HDU 3401 Trade(单调队列优化DP)【模板】
来源:互联网 发布:知乎lolfaker 编辑:程序博客网 时间:2024/05/22 11:35
题目链接:点击打开链接
【题解】
大致题意:有人发现了股票的规律,现在抱着多赚钱的想法,想在t天后获得最大收益,现已知他任意时刻手里只能持有maxp份股票,而且每股股票买了后w+1天才可以再次交易(继续卖或者买或者不动),不仅如此,已知每天每股股票买入价是buy[i],卖出价是sell[i],每天的买入数最多spa[i],卖出最多spb[i]。 求t天后的最大收益。
分析:
初一看题目很复杂,条件限制很多,不要慌,慢慢梳理。
用数组dp[i][j]表示第 i 天持有 j 股股票的最大收益。
那么总共可以分三种情况:
1)不买不卖 dp[i][j] = max(dp[i][j],dp[i-1][j]);
2)买了股票 dp[i][j] = max(dp[i][j],dp[i-W-1][k] - (j - k) * AP[i]);
3)卖了股票 dp[i][j] = max(dp[i][j],dp[i-W-1][k] + (k - j) * BP[i]);
如果用普通的枚举法算,复杂度是立方级的,所以要优化。
买票的转移方程转化一下就是dp[i][j]=max(dp[i][j] , dp[i-W-1][k]+k*AP[i]-j*AP[i] ;
令f[i-W-1] = dp[i-W-1][k] + k * AP[i];
那么dp[i][j] = max(f[i-W-1]) - j * AP[i];对于f[i-W-1]可以用单调队列来求。这样复杂度就成了n ^ 2。买股票的也类似。
【AC代码】
#include<iostream>#include<algorithm>#include<cstdio>#include<cstring>#include<queue>#include<stack>using namespace std;const int N=2005;const int inf=1e9;int m,maxp,W,T,spa[N],spb[N];int buy[N],sell[N];int dp[2002][2002];struct node{ int x; int pos;}ss[N];int head,tail;int main(){ int t; scanf("%d",&t); while(t--) { scanf("%d%d%d",&T,&maxp,&W); for(int i=1;i<=T;++i) scanf("%d%d%d%d",&buy[i],&sell[i],&spa[i],&spb[i]); for(int i=0;i<=T;++i) for(int j=0;j<=maxp;++j) dp[i][j]=-inf; for(int i=1;i<=W+1;++i) for(int j=0;j<=min(maxp,spa[i]);++j) dp[i][j]=-buy[i]*j; //特殊处理 dp[0][0]=0; for(int i=1;i<=T;++i) { for(int j=0;j<=maxp;++j) //不买不卖 dp[i][j]=max(dp[i][j],dp[i-1][j]); if(i<=W+1) continue;//还不到w+1天 ,不能买 int pre=i-W-1;// w+1 天后 head=tail=0; //单调队列 for(int j=0;j<=maxp;++j)// 遍历手中的股票数 { int newx=dp[pre][j]+j*buy[i];//i-W-1天前j股可以赚的钱+买j股票花的钱 while(head<tail && ss[tail-1].x<newx) tail--; ss[tail].x=newx; ss[tail++].pos=j; while(head<tail && ss[head].pos+spa[i]<j) head++; dp[i][j]=max(dp[i][j],ss[head].x-j*buy[i]); } head=tail=0; //同上 for(int j=maxp;j>=0;--j) { int newx=dp[pre][j]+j*sell[i]; while(head<tail && ss[tail-1].x<newx) tail--; ss[tail].x=newx; ss[tail++].pos=j; while(head<tail&& ss[head].pos-spb[i]>j) head++; dp[i][j]=max(dp[i][j],ss[head].x-j*sell[i]); } } int ans=0; for(int i=0;i<=maxp;++i) //遍历 寻找第T天手中有i股股票时的最大收益 ans=max(ans,dp[T][i]); printf("%d\n",ans); } return 0;}
阅读全文
1 0
- HDU 3401 Trade(单调队列优化DP)【模板】
- hdu 3401 Trade(DP+单调队列优化)
- hdu 3401 Trade 单调队列优化dp
- hdu 3401 Trade 单调队列优化dp
- hdu 3401 Trade(单调队列优化dp)
- HDU 3401 Trade 单调队列优化DP
- HDU 3401 Trade 【DP+单调队列优化】
- HDU 3401 Trade (单调队列优化DP)
- HDU-3401:Trade(dp+单调队列优化)
- HDU 3401 Trade(用单调队列优化DP)
- hdu 3401 Trade (单调队列优化)
- hdu-3401-Trade-单调队列优化的DP
- hdu3401 Trade(单调队列优化dp)
- Trade HDU 3401 单调队列DP
- hdu 3401 Trade //单调队列+DP
- HDU 3401 Trade【单调队列+dp】
- hdu 3401 Trade 单调队列+dp
- hdu 3401 Trade dp+单调队列
- 邻接链表的构建
- 矩阵乘法
- Maven项目下WEB-INFO目录下没有编译的classes文件
- 【C语言】栈演示(栈的几个函数)
- HDU 3430 置换群 + 同余方程组
- HDU 3401 Trade(单调队列优化DP)【模板】
- 2017.08.07回顾
- 【BashuOJ1145】虚-组合数+求逆元
- 命令行编译运行从c,c++,java
- 导入导出Excel文件
- nodejs 构建本地web测试服务器 以及 解决访问静态资源的问题!有完整源码!
- React学习总结—生命周期
- codeforces838A Binary Blocks
- unity3D学习之音频基础原理-audio菜鸟笔记3