hdu 3401(单调队列优化dp)
2017-10-15 17:36
337 查看
传送门
题解:
构造状态dp[i][j]表示第i 天拥有 j只股票的时候,赚了多少钱
从前一天不买不卖 dp[i][j]=max(dp[i-1][j],dp[i][j])
从前i-W-1天买进一些股 dp[i][j]=max(dp[i-W-1][k]-(j-k)*AP[i],dp[i][j])
从i-W-1天卖掉一些股 dp[i][j]=max(dp[i-W-1][k]+(k-j)*BP[i],dp[i][j])
为什么只考虑第i-W-1天的买入卖出情况即可。想想看,i-W-2天是不是可以通过不买不卖将自己的最优状态转移到第i-W-1天?以此类推,之前的都不需要考虑了,只考虑都i-W-1天的情况即可。
对买入股票的情况进行分析,转化成适合单调队列优化的方程形式
dp[i][j]=max(dp[i-W-1][k]+k*AP[i])-j*AP[i]。令f[i-W-1][k]=dp[i-W-1][k]+k*AP[i],则dp[i][j]=max(f[i-W-1][k]) - j*AP[i]。
P.S.1~w+1天不能更新。还有,dp转移时一定要加一句if,否则会出现不合法转移(比如卖股票时q[t] - j < 0)
题解:
构造状态dp[i][j]表示第i 天拥有 j只股票的时候,赚了多少钱
从前一天不买不卖 dp[i][j]=max(dp[i-1][j],dp[i][j])
从前i-W-1天买进一些股 dp[i][j]=max(dp[i-W-1][k]-(j-k)*AP[i],dp[i][j])
从i-W-1天卖掉一些股 dp[i][j]=max(dp[i-W-1][k]+(k-j)*BP[i],dp[i][j])
为什么只考虑第i-W-1天的买入卖出情况即可。想想看,i-W-2天是不是可以通过不买不卖将自己的最优状态转移到第i-W-1天?以此类推,之前的都不需要考虑了,只考虑都i-W-1天的情况即可。
对买入股票的情况进行分析,转化成适合单调队列优化的方程形式
dp[i][j]=max(dp[i-W-1][k]+k*AP[i])-j*AP[i]。令f[i-W-1][k]=dp[i-W-1][k]+k*AP[i],则dp[i][j]=max(f[i-W-1][k]) - j*AP[i]。
P.S.1~w+1天不能更新。还有,dp转移时一定要加一句if,否则会出现不合法转移(比如卖股票时q[t] - j < 0)
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int MAXN=2004; int n,m,w,dp[MAXN][MAXN]; int ap[MAXN],as[MAXN],bp[MAXN],bs[MAXN]; int q[MAXN],h,t; inline int read() { int x=0,f=1;char c=getchar(); while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();} while (c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); return x*f; } int main() { // freopen("hdu 3401.in","r",stdin); int kase=read(); while (kase--) { n=read(),m=read(),w=read(); for (int i=1;i<=n;++i) ap[i]=read(),bp[i]=read(),as[i]=read(),bs[i]=read(); memset(dp,-0x3f,sizeof(dp)); dp[0][0]=0; for (int i=1;i<=w+1;++i) for (int j=0;j<=min(as[i],m);++j) dp[i][j]=-ap[i]*j; for (int i=1;i<=n;++i) { for (int j=0;j<=m;++j) dp[i][j]=max(dp[i-1][j],dp[i][j]); if (i<=w+1) continue; int pre=i-w-1; h=1,t=0; for (int j=0;j<=m;++j) { while (h<=t&&q[h]+as[i]<j) ++h; if (q[h]<=j) dp[i][j]=max(dp[i][j],dp[pre][q[h]]-ap[i]*(j-q[h])); while (h<=t&&dp[pre][q[t]]-ap[i]*(j-q[t])<dp[pre][j]) --t; q[++t]=j; } h=1,t=0; for (int j=m;~j;--j) { while (h<=t&&q[h]-bs[i]>j) ++h; if (q[h]>=j) dp[i][j]=max(dp[i][j],dp[pre][q[h]]+bp[i]*(q[h]-j)); while (h<=t&&dp[pre][q[t]]+bp[i]*(q[t]-j)<dp[pre][j]) --t; q[++t]=j; } } int ans=0; for (int j=0;j<=m;++j) ans=max(ans,dp [j]); printf("%d\n",ans); } return 0; }
相关文章推荐
- HDU 3401 Trade 【DP+单调队列优化】
- hdu 3401 Trade 单调队列优化dp
- HDU 3401 Trade 单调队列优化DP
- hdu 3401 单调队列优化DP
- hdu 3401 Trade 单调队列优化dp
- Hdu 3401 题解 单调队列优化DP
- hdu 3401 Trade(DP+单调队列优化)
- hdu 3401 单调队列优化DP
- HDU 3401 Trade (单调队列优化DP)
- 股票交易 【SCOI 2010】HDU 3401 (单调队列优化DP入门)
- hdu 3401(单调队列优化dp)
- HDU - 3401 单调队列优化DP
- hdu-3401-Trade-单调队列优化的DP
- HDU 3401 Trade(用单调队列优化DP)
- hdu 3401 Trade(单调队列优化dp)
- HDU-3401:Trade(dp+单调队列优化)
- 【HDU 3401 Trade】 单调队列优化dp
- HDU 3401 单调队列优化DP
- hdu 3401 单调队列优化dp
- 【单调队列优化dp】HDU 3401 Trade