HDU 3401 Trade 单调队列优化DP
来源:互联网 发布:spycall的软件 编辑:程序博客网 时间:2024/05/06 06:42
【题目链接】 点击打开链接
【题意】 大概就是说一个人现在炒股,他有两种操作,一种是买股票(这个当然是花钱), 一个是卖股票(这里钦定为挣钱)。然后每个人在每天买和卖股票的数量是有限制的,并且还有一个限制是一个人拥有的股票数不能超过MaxP。还有一个人执行操作的间隔必须大于W。问这个人最后最多挣多少钱?
【解题方法】
我们可以大胆的写出一个朴素的DP方程: dp[i][j] 表示第 i 天,拥有股票数目为 j 的时候赚了多少钱?那么DP分为3种情况: (1) 前一天不买不卖,从前一天转移过来 dp[i][j] = max(dp[i][j], dp[i-1][j]) (2) 前i - w - 1天买进一些股。 dp[i][j] = max(dp[i][j], dp[i - w - 1][k] + (j - k) * AP[i]); (3) 前i - w - 1天卖掉一些股。 dp[i][j] = max(dp[i][j], dp[i - w - 1][k] + (k - j) * BP[i]);好的,到现在为止,我们的朴素DP方程就推完了,或许这里有个疑惑?为什么是从i - w - 1转移就行了呢? 这里考虑下 i - w - 1的状态 可以由 i - w - 2的状态不买不卖,转移过来, 那么我们就可以放心的使用这个DP了。 我们来想一下这个DP的复杂度? 枚举i, j, k 显然是 O(Maxp * n * n), 这显然炸掉的复杂度, 题目只有1000ms。那么我们怎么优化呢? 我们把DP来变一下形状,发现第2个dp可以写成 : dp[i][j] = max(dp[i - w - 1][k] - (j * AP[i] - k * AP[i]) = dp[i - w - 1][k] + k * AP[i] - j * AP[i]; 让f[i - 1][j] = dp[i - w - 1][k] + k * AP[i]; g[i][j] = - j * AP[i]; 这个式子又转化成了标准的单调队列优化,我们的复杂度可以顺利降为 O(MaxP * n), 就可以通过这个题了。
【AC代码】
////Created by BLUEBUFF 2016/1/8//Copyright (c) 2016 BLUEBUFF.All Rights Reserved//#pragma comment(linker,"/STACK:102400000,102400000")#include <ext/pb_ds/assoc_container.hpp>#include <ext/pb_ds/tree_policy.hpp>#include <ext/pb_ds/hash_policy.hpp>#include <set>#include <map>#include <queue>#include <stack>#include <cmath>#include <cstdio>#include <time.h>#include <cstdlib>#include <cstring>#include <sstream> //isstringstream#include <iostream>#include <algorithm>using namespace std;//using namespace __gnu_pbds;typedef long long LL;typedef pair<int, LL> pp;#define REP1(i, a, b) for(int i = a; i < b; i++)#define REP2(i, a, b) for(int i = a; i <= b; i++)#define REP3(i, a, b) for(int i = a; i >= b; i--)#define CLR(a, b) memset(a, b, sizeof(a))#define MP(x, y) make_pair(x,y)const int maxn = 220;const int maxm = 2e5;const int maxs = 10;const int maxp = 1e3 + 10;const int INF = 1e9;const int UNF = -1e9;const int mod = 1e9 + 7;int gcd(int x, int y) {return y == 0 ? x : gcd(y, x % y);}//typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update>order_set;//headstruct node{ int pos, f;}que1[2010];//维护单调递减栈int AP[2010], BP[2010], AS[2010], BS[2010];int dp[2010][2010];int n, MaxP, w, head1, tail1;int main(){ int T; scanf("%d", &T); while(T--) { scanf("%d%d%d", &n, &MaxP, &w); for(int i = 1; i <= n; i++) scanf("%d%d%d%d", &AP[i], &BP[i], &AS[i], &BS[i]); //init head1 = tail1 = 0; CLR(que1, 0); for(int i = 0; i <= n; i++){ for(int j = 0; j <= MaxP; j++){ dp[i][j] = UNF; } } for(int i = 1; i <= w + 1; i++){ for(int j = 0; j <= min(MaxP, AS[i]); j++){ dp[i][j] = -AP[i] * j; } } dp[0][0] = 0; // for(int i = 1; i <= n; i++){//枚举天数 for(int j = 0; j <= MaxP; j++){ dp[i][j] = max(dp[i][j], dp[i-1][j]); } if(i <= w + 1) continue; head1 = tail1 = 0; for(int j = 0; j <= MaxP; j++){ int nowf = dp[i - w - 1][j] + j * AP[i]; while(head1 < tail1 && que1[head1].pos + AS[i] < j) head1++; while(head1 < tail1 && que1[tail1 - 1].f < nowf) tail1--; que1[tail1].f = nowf, que1[tail1].pos = j; tail1++; dp[i][j] = max(dp[i][j], que1[head1].f - j * AP[i]); } head1 = tail1 = 0; for(int j = MaxP; j >= 0; j--){ int nowf = dp[i - w - 1][j] + j * BP[i]; while(head1 < tail1 && que1[head1].pos - BS[i] > j) head1++; while(head1 < tail1 && que1[tail1 - 1].f < nowf) tail1--; que1[tail1].f = nowf, que1[tail1].pos = j, tail1++; dp[i][j] = max(dp[i][j], que1[head1].f - j * BP[i]); } } // int ans = 0; for(int i = 0; i <= MaxP; i++){ ans = max(ans, dp[n][i]); } cout << ans << endl; } return 0;}
0 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(用单调队列优化DP)
- Trade 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 Trade (单调队列优化)
- poj 3801 Crazy Circuits (有源汇有上下界的最小流)
- C++ 虚函数表解析
- 1分钟完成MySQL5.6生产库自动化安装部署
- boost 1.56.0 编译及使用
- Matplotlib 中文用户指南 3.2 图像教程
- HDU 3401 Trade 单调队列优化DP
- RS-232相关
- 学习C++推荐书籍
- 17 - 02 - 18 计算机网络(39)(KPI/数字证书)
- Spring3事务管理——使用原始的TransactionProxyFactoryBean
- leetcode27:Remove Element
- windows无法找到发送到桌面快捷方式
- 七个“千僖年数学难题”
- Struts2学习笔记(1)