POJ1821-Fence
来源:互联网 发布:进出口海关数据 编辑:程序博客网 时间:2024/05/01 18:54
这是一道经典的单调队列优化DP.
首先不难看出要用动态规划求解,dp[i][j]表示第i个工人粉刷第j块木板时的最大收益,由此
dp[i][j] = max(
dp[i-1][j] 第i个工人不刷木板
dp[i-1][k] + (j - k) * p 第i个工人从第k+1块木板开始一直刷到第j块
)
由于每个工人粉刷的木板必须包含s,因此dp[i][…]只跟dp[i-1][…]有关。
另外前两个方程已经是O(1)时间的,而第三个方程可以变为
max(dp[i-1][k] - k * p) + j * p,因此我们将括号内的数值用一个单调队列维护,然后枚举i,j,k即可。
维护单调队列时我们保证val(dp[i-1][k] - k * p)从大到下,pos从小到大,从队尾不断删除比要插入的小的值,查询时从队首不断抛出,第一个满足位置区间的即是最大的满足条件的val。
注意k是已经粉刷完毕的最后一块木板,k+1是该工人需要粉刷的第一块木板,而j是最后一块需要粉刷的木板:
s - l + 1 <= k + 1 <= s
s - l <= k < s
s <= j <= j + l - 1
搞定需要枚举的区间后剩下的就很简单了。
#include <cstdio>#include <deque>#include <algorithm>using namespace std;const int maxn = 160000 + 10;const int maxm = 100 + 10;struct worker { int l, p, s; bool operator < (const worker& w) const { return s < w.s; }};worker a[maxm];int dp[maxm][maxn];// dp[i][j] = dp[i-1][k] + (j-k) * pint main(int argc, char const *argv[]) { int n, m; scanf("%d%d", &n, &m); for (int i = 1; i <= m; i++) { scanf("%d%d%d", &a[i].l, &a[i].p, &a[i].s); } sort(a + 1, a + m + 1); for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { dp[i][j] = dp[i-1][j]; } //first == val, second == pos deque<pair<int, int> > deq; for (int k = max(a[i].s - a[i].l, 0); k < a[i].s; k++) { int val = dp[i-1][k] - k * a[i].p; while (!deq.empty() && deq.back().first <= val) { deq.pop_back(); } deq.push_back(make_pair(val, k)); } for (int j = a[i].s; j < a[i].s + a[i].l; j++) { while (!deq.empty() && deq.front().second < j - a[i].l) { deq.pop_front(); } dp[i][j] = max(dp[i][j],deq.front().first + j * a[i].p); } } printf("%d\n", *max_element(dp[m] + 1, dp[m] + n + 1)); return 0;}
0 0
- poj1821 Fence
- POJ1821-Fence
- POJ1821-Fence
- POJ1821-Fence
- poj1821 Fence,dp
- 单调队列 poj1821 Fence
- poj1821 Fence 单调队列dp
- 【poj1821】Fence 单调队列优化DP
- [poj1821] Fence DP单调队列优化
- fence
- Fence
- Fence
- Fence
- poj1821 单调队列优化
- 单调队列优化dp [HDU2191][HDU3401][POJ1821]
- Memory Fence
- Electric Fence
- poj1031 fence
- php中__autoload()函数是如何运作的?
- Swift学习:2.1 基础部分
- Nodejs在ubuntu中安装
- Red5流媒体服务器开发总结
- 编码问题
- POJ1821-Fence
- (0)Java学习笔记之绪论 --- 学什么
- apache的多个站点配置
- java源码学习2-Integer
- **浙大PAT甲级 1105
- 同桌的你
- Swift学习:2.2 基本运算符
- ubuntu 下的限速软件 wondershaper 以及 命令行测试网速
- android 获取SD卡里的所有TXT文件