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 ...
随机推荐
- Git&GitHub-初步使用
Git 1.安装 下载安装包,安装,默认安装了 Git GUI Here 和 Git Bash Here. 需要在哪里使用 git,只需在文件夹空白处右键,选择Git Bash Here即可打开 gi ...
- Hibernate 事务不回滚
问题: 这几天在做开发时,发现事务不回滚了,Service是用AOP加的事务,数据库是MySql, 表全部是InnoDB: 方法回滚是采用spring的手动回滚: ...
- iOS 打包常见问题处理
Cannot proceed with delivery: an existing transporter instance is currently uploading this package 原 ...
- [Java]Java 9运行Spring Boot项目报错的解决办法
简介 为了学习和尽快掌握 Java 9 的模块化(Module System)新特性,最近安装了 JDK 9,新建了一个 Spring Boot 进行尝试, 过程中遇到了一下报错问题,写下此文谨作为个 ...
- Mysql是否开启binlog日志&开启方法
运行sql show variables like 'log_bin'; 如果Value 为 OFF 则为开启日志文件 如何开启mysql日志? 找到my,cnf 中 [mysqld] 添加如下 ...
- PHP封装CURL
CURL是一个非常强大的开源库,支持很多协议,包括HTTP.FTP.TELNET等,我们使用它来发送HTTP请求.它给我 们带来的好处是可以通过灵活的选项设置不同的HTTP协议参数,并且支持HTTPS ...
- 基于OMAPL138的字符驱动_GPIO驱动AD9833(三)之中断申请IRQ
基于OMAPL138的字符驱动_GPIO驱动AD9833(三)之中断申请IRQ 0. 导语 学习进入到了下一个阶段,还是以AD9833为例,这次学习是向设备申请中断,实现触发,在未来很多场景,比如做用 ...
- Python学习笔记七:文件操作
文件操作 对照一个word文件的操作方式,来体会文件操作的内容 打开文件:f=open(“file”),提示编码错误,windows默认是GBK f=open(“file”,encoding=”utf ...
- 北京Uber优步司机奖励政策(3月22日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- 北京Uber优步司机奖励政策(1月30日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...