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. Python入门 —— 01简介

    Python 历史 python 的创始人为荷兰人吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程序,作为 ...

  2. Asp.Net Core链接Mysql数据库

    一.新建一个Asp.Net Core WebMVC程序 添加nuget包  Mysql.Data 二.新建一个UserContext类 下面代码中的UserInfo是我自己建的一个实体,里面有俩字段: ...

  3. hadoop生态搭建(3节点)-17.sqoop配置_单节点

    # ==================================================================安装 sqoop tar -zxvf ~/sqoop-1.4.7 ...

  4. python2x和python3x的一些区别

    python2x:各种按照自己代码习惯给python贡献源码 python3x:重写之后的源码,优美,清晰,简单 版本 打印函数 rang函数 输入函数 python2x print 或 print( ...

  5. Python写网络后台脚本

    Python写网络后台脚本. 首先安装Python3.6.5,在centos中自带的Python是2.6版本的,现在早就出现了3.6版本了况且2和3 之间的差距还是比较大的,所以我选择更新一下Pyth ...

  6. go内建容器-字符和字符串操作

    1.基础定义 在基础语法篇提到过golang的rune相当于其他编程语言的char,其本质是一个int32(四字节),用[]rune来转换一个字符串时,得到的是个解码后的结果,存储在新开辟的[]run ...

  7. MapWindow记录

    增加MapWinGIS的新功能,编译完MapWinGIS,可以生成Debug和Release版本的x64和Win32四种版本, 自己基于c#的Mapwindow如果要用到新添加的功能,此时就得重新注册 ...

  8. 优步UBER司机全国各地奖励政策汇总 (2月1日-2月7日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  9. 北京Uber优步司机奖励政策(1月15日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  10. mysql题目练习的答案

    rianley 博客 盗版必究!基于上一个sql练习的答案:该答案是我所写!如果有错误或者用法不当之处:请下方评论指出:感激不尽!谢谢各位码友! <!--1.查询所有的课程的名称以及对应的任课老 ...