Description

Panagola, The Lord of city F likes to parade very much. He always inspects his city in his car and enjoys the welcome of his citizens. City F has a regular road system. It looks like a matrix with n+1 west-east roads and m+1 north-south roads. Of course, there are (n+1)×(m+1) road crosses in that system. The parade can start at any cross in the southernmost road and end at any cross in the northernmost road. Panagola will never travel from north to south or pass a cross more than once. Citizens will see Panagola along the sides of every west-east road. People who love Panagola will give him a warm welcome and those who hate him will throw eggs and tomatoes instead. We call a road segment connecting two adjacent crosses in a west-east road a “love-hate zone”. Obviously there are m love-hate zones in every west-east road. When passing a love-hate zone, Panagola may get happier or less happy, depending on how many people love him or hate him in that zone. So we can give every love-hate zone a “welcome value” which may be negative, zero or positive. As his secretary, you must make Panagola as happy as possible. So you have to find out the best route ----- of which the sum of the welcome values is maximal. You decide where to start the parade and where to end it.

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

There are multiple test cases. Input ends with a line containing three zeros.  Each test case consists of 2×n + 3 lines. 
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

For each test case, output the sum of welcome values of the best route. The answer can be fit in a 32 bits integer.

题目大意:有一个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)的更多相关文章

  1. HDU 3401 Trade dp+单调队列优化

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3401 Trade Time Limit: 2000/1000 MS (Java/Others)Mem ...

  2. HDU - 3415(DP + 单调队列)

    链接:HDU - 3415 题意:给出一个包含 n 个数的环,求满足长度大于 0 小于等于 k 的最大区间和. 题解:将数组加倍,形成环.求一个前缀和sum.枚举每一个sum[i],以 i 结尾的最大 ...

  3. HDU 5945 题解(DP)(单调队列)

    题面: Fxx and game Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others) T ...

  4. hdu 4123 树形DP+单调队列

    http://acm.hust.edu.cn/vjudge/problem/25790 这题基本同poj 3162 要注意mx,mx2,vx,vx2每次都要初始化 #include <iostr ...

  5. HDU 4749 Parade Show 2013 ACM/ICPC Asia Regional Nanjing Online

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4749 题目大意:给一个原序列N,再给出一个序列M,问从N中一共可以找出多少个长度为m的序列,序列中的数 ...

  6. 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 ...

  7. 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 ...

  8. 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 ...

  9. 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 ...

随机推荐

  1. 在mac下运行 npm run eject 出现报错问题解决方法

    当使用create-react-app创建项目后,接着运行npm run eject时,如果出现下面的错误 可能是脚手架添加了.gitignore这个文件,但是没有本地仓库,可以使用以下代码解决这个问 ...

  2. Linux Centos6.5 升级默认Python2.6.6到Python2.7.13

    以下例子基于python 2.7.9,其他版本同理.大致的命令都是差不多的,安装完成之后,输入Python --vertion ,看到系统默认的版本已经替换为2.7版本了 1.下载python wge ...

  3. 基于JQ的简版选项卡记录

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  4. 线上服务内存OOM问题定位三板斧

    相信大家都有感触,线上服务内存OOM的问题,是最难定位的问题,不过归根结底,最常见的原因: 本身资源不够 申请的太多 资源耗尽 58到家架构部,运维部,58速运技术部联合进行了一次线上服务内存OOM问 ...

  5. 大数据学习--day11(抽象类、接口、equals、compareTo)

    抽象类.接口.equals.compareTo 什么是抽象方法  ?     区分于正常的方法       1.使用了 abstract 修饰符          该修饰符修饰方法 则该方法就是抽象方 ...

  6. LinkedList的源码分析(基于jdk1.8)

    1.初始化 public LinkedList() { } 并未开辟任何类似于数组一样的存储空间,那么链表是如何存储元素的呢? 2.Node类型 存储到链表中的元素会被封装为一个Node类型的结点.并 ...

  7. java对象转map

    /** * java对象转map * @param obj * @return * @throws IllegalAccessException * @throws IllegalArgumentEx ...

  8. 20145209刘一阳《网络对抗》Exp6信息搜集与漏洞扫描

    20145209刘一阳<网络对抗>Exp6信息搜集与漏洞扫描 实践内容 信息搜集和漏洞扫描 信息搜集 whois查询 用whois查询博客园网站的域名注册信息可以得到注册人的名字.城市等信 ...

  9. 成都优步uber司机第五组奖励政策

    7月14日,成都优步uber团队发布了第五组用户分组.在传言要推出第四组的时候,心想事不过三吧,意外,现在第五组都出来了.一起看看成都优步司机第五组的详细内容!滴滴快车单单2.5倍,注册地址:http ...

  10. CakePHP 查询总结

    返回 $this->Post->buildQuery(); 返回: Array ( [conditions] => [fields] => [joins] => Arra ...