HDU 2490 Parade(DPの单调队列)(2008 Asia Regional Beijing)
Description
When seeing his Citizens, Panagola always waves his hands. He may get tired and need a break. So please never make Panagola travel in a same west-east road for more than k minutes. If it takes p minutes to pass a love-hate zone, we say the length of that love-hate zone is p. Of course you know every love-hate zone’s length.
The figure below illustrates the case in sample input. In this figure, a best route is marked by thicker lines.
Input
The first line contains three integers: n, m and k.(0<n<=100,0<m<=10000, 0<=k<=3000000)
The next n+1 lines stands for n + 1 west-east roads in north to south order. Each line contains m integers showing the welcome values of the road’s m love-hate zones, in west to east order.
The last n+1 lines also stands for n + 1 west-east roads in north to south order. Each line contains m integers showing the lengths (in minutes) of the road's m love-hate zones, in west to east order.
Output
题目大意:有一个n*m的矩阵,只能沿着边走,只能往左、往右或往上走,在同一行只能沿一个方向走(走了左边就不能返回走右边了)。打横的边都有一个权值(可能为负数)和一个长度,每行走过的长度不能超过k,打竖的边没有权值和长度。先要从最下面的任意一个点开始,走到最上面的任意一个点,问最大权值和为多少(答案不超过$2^{31}-1$,虽然题目不是这么说的)。
思路:一看就是动态规划,每一行只和上一行的状态有关。因为习惯从小到大循环我们从上往下走,反正都一样。设dp[i][j]为走到第 i 行第 j 个点的最大权值(已往左往右走完),那么dp[i][j] = max(dp[i-1][x] + sum(welcome[i][y])),distance(x, y) ≤ k,y in [x, i]。其中distance和sum(welcome[i][y])可以预处理出来(如sum[i]代表1~i的和,distance(i, j) = sum[j] - sum[i],i ≤ j),平均到处理每个dp[i][j]身上时间复杂度为O(1)。但是这样计算dp数组,时间复杂度高达$O(nm^2)$。
现假设我们从左到右走,那么dp[i][j] = max(dp[i - 1][x] - sum_welcome[x] + sum_welcome[y]) = dp[i][j] = max(dp[i - 1][x] - sum_welcome[x]) + sum_welcome[y],那么对每一个j,所用的dp[i - 1][x] - sum_welcome[x]都是一样的,这里很容易能想到单调队列优化(如果你知道单调队列的话)。每次把队列末尾小于dp[i - 1][j] - sum_welcome[j]弹出,把队头distance(i, x) > k的弹出,队头就是最佳的dp[i - 1][x] - sum_welcome[x]。优化完时间复杂度为$O(nm)$,已经是读入数据的复杂度了。(这里不介绍单调队列)
PS:可恶这题居然不让人在线非要我把整个矩阵一起读进来……
代码(1078MS,可恶啊C++又比G++快一倍):
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std; const int MAXN = ;
const int MAXM = ; int wel[MAXN][MAXM], len[MAXN][MAXM];
int sum_w[MAXM], sum_l[MAXM];
int a[MAXM], b[MAXM], head, tail;
int dp[][MAXM];
int n, m, k, cur; inline void insert(int x, int y) {
while(head != tail && a[tail - ] < x) --tail;
a[tail] = x; b[tail] = y; ++tail;
} void solve() {
memset(dp, , sizeof(dp));
cur = ;
for(int i = ; i < n; ++i) {
cur ^= ;
memset(dp[cur], , sizeof(dp[cur])); sum_w[] = sum_l[] = ;
for(int j = ; j <= m; ++j) sum_w[j] = sum_w[j - ] + wel[i][j];
for(int j = ; j <= m; ++j) sum_l[j] = sum_l[j - ] + len[i][j];
head = tail = ;
for(int j = ; j <= m; ++j) {
insert(dp[cur ^ ][j] - sum_w[j], sum_l[j]);
while(k < sum_l[j] - b[head]) ++head;
dp[cur][j] = max(dp[cur][j], a[head] + sum_w[j]);
} sum_w[m] = sum_l[m] = ;
for(int j = m; j > ; --j) sum_w[j - ] = sum_w[j] + wel[i][j];
for(int j = m; j > ; --j) sum_l[j - ] = sum_l[j] + len[i][j];
head = tail = ;
for(int j = m; j >= ; --j) {
insert(dp[cur ^ ][j] - sum_w[j], sum_l[j]);
while(k < sum_l[j] - b[head]) ++head;
dp[cur][j] = max(dp[cur][j], a[head] + sum_w[j]);
}
}
} int main() {
while(scanf("%d%d%d", &n, &m, &k) != EOF) {
if(n == && m == && k == ) break;
++n;
for(int i = ; i < n; ++i)
for(int j = ; j <= m; ++j) scanf("%d", &wel[i][j]);
for(int i = ; i < n; ++i)
for(int j = ; j <= m; ++j) scanf("%d", &len[i][j]);
solve();
int ans = ;
for(int i = ; i <= m; ++i) ans = max(ans, dp[cur][i]);
printf("%d\n", ans);
}
}
HDU 2490 Parade(DPの单调队列)(2008 Asia Regional Beijing)的更多相关文章
- HDU 3401 Trade dp+单调队列优化
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3401 Trade Time Limit: 2000/1000 MS (Java/Others)Mem ...
- HDU - 3415(DP + 单调队列)
链接:HDU - 3415 题意:给出一个包含 n 个数的环,求满足长度大于 0 小于等于 k 的最大区间和. 题解:将数组加倍,形成环.求一个前缀和sum.枚举每一个sum[i],以 i 结尾的最大 ...
- HDU 5945 题解(DP)(单调队列)
题面: Fxx and game Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others) T ...
- hdu 4123 树形DP+单调队列
http://acm.hust.edu.cn/vjudge/problem/25790 这题基本同poj 3162 要注意mx,mx2,vx,vx2每次都要初始化 #include <iostr ...
- HDU 4749 Parade Show 2013 ACM/ICPC Asia Regional Nanjing Online
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4749 题目大意:给一个原序列N,再给出一个序列M,问从N中一共可以找出多少个长度为m的序列,序列中的数 ...
- HDU 2494/POJ 3930 Elevator(模拟)(2008 Asia Regional Beijing)
Description Too worrying about the house price bubble, poor Mike sold his house and rent an apartmen ...
- HDU 2492 Ping pong(数学+树状数组)(2008 Asia Regional Beijing)
Description N(3<=N<=20000) ping pong players live along a west-east street(consider the street ...
- HDU 2491 Priest John's Busiest Day(贪心)(2008 Asia Regional Beijing)
Description John is the only priest in his town. October 26th is the John's busiest day in a year be ...
- HDU 2489 Minimal Ratio Tree(暴力+最小生成树)(2008 Asia Regional Beijing)
Description For a tree, which nodes and edges are all weighted, the ratio of it is calculated accord ...
随机推荐
- 【算法笔记】B1010 一元多项式求导
1010 一元多项式求导 (25 分) 设计函数求一元多项式的导数.(注:xn(n为整数)的一阶导数为nxn−1.) 输入格式: 以指数递降方式输入多项式非零项系数和指数(绝对值均为不超过 ...
- chromium之histogram.h
histogram不知道是干啥的 // Histogram is an object that aggregates statistics, and can summarize them in // ...
- MySQL数据导入导出(一)
今天遇到一个需求,要用自动任务将一张表的数据导入另一张表.具体场景及限制:将数据库A中表A的数据导入到数据库B的表B中(增量数据或全量数据两种方式):体系1和体系2只能分别访问数据库A和数据库B.附图 ...
- jQuery.qrcode 生成二维码,并使用 jszip、FileSaver 下载 zip 压缩包至本地。
生成二维码 引用 jquery.qrcode.js :连接:https://files.cnblogs.com/files/kitty-blog/jquery.qrcode.js .https:// ...
- 多用户OFDM系统资源分配研究
首先,OFDMA 是什么? OFDM 技术的基本原理是将无线信道划分为若干互相正交的子信道,把高速串行数据流转化为低速并行子数据流,低速并行子数据流在子信道上独立传输. OFDMA 是LTE的下行多址 ...
- mysql的docker化安装
mysql版本有很多,先看下各类版本号说明: 3.X至5.1.X:这是早期MySQL的版本.常见早期的版本有:4.1.7.5.0.56等. 5.4.X到5.7.X:这是为了整合MySQL AB公司社区 ...
- django的render的特殊用法
以前都是将模板渲染好, 传输到前端, 但是现在前后端分离了, 模板渲染引擎还有用, 而且很好用. 比如在渲染一个表格的时候, 每一行都有两个操作按钮, 并且这个按钮上是有a标签的 你可以使用字符串拼接 ...
- win10 下安装 MongoDB 数据库支持模块(python)
C:\>pythonPython 3.5.2 (v3.5.2:4def2a2901a5, Jun 25 2016, 22:18:55) [MSC v.1900 64 bit (AMD64)] o ...
- ACM数论-卡特兰数Catalan
Catalan 原理: 令h(0)=1,h(1)=1,catalan 数满足递归式: (其中n>=2) 另类递推公式: 该递推关系的解为: (n=1,2,3,...) 卡特兰数的应用实质上都是递 ...
- BINARYSEARCH有り無しのパフォーマンスの違い
BINARY SEARCHを使用したパフォーマンス検証を行ってみた.この例では.BKPFが約1万件.BSEGが約3万件になるよう調整している.また.SQLの実行に係る時間は無視する事にする. サンプル ...