题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2490

Parade

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 902    Accepted Submission(s): 396

Problem 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.
 
Sample Input
2 3 2
7 8 1
4 5 6
1 2 3
1 1 1
1 1 1
1 1 1
0 0 0
 
Sample Output
27
 
Source
 题意: F城是由n+1条横向路和m+1条竖向路组成。你的任务是从最南边的路走到最北边的路,使得走过的路上的高兴值和最大(注意,一段路上的高兴值可能是负 数)。同一段路不能经过两次,且不能从北往南走,另外,在每条横向路上所花的时间不能超过k。求从南到北走完可以获得的最大高兴值。
题解: 学习dp 任何一个状态可以是由下一行的-k<t<k 的状态转移过来,所以是一个dp问题,现在先预处理出每一行到当前位置的前缀和用sum[i][j]保存下来,
dp[i][j]表示到第i行第j列的时候最大的高兴值,这个时候下一行的dp[i+1][j]已经处理出来了
假设当前位置是由下一行的第k个格子转移来的,当k<=j 的时候有 dp[i][j] = dp[i+1][k] + sum[i+1][j] - sum[i+1][k] ——(1式)
                       当k>  j 的时候有 dp[i][j] = dp[i+1][k] + sum[i+1][k] - sum[i+1][j] ——(2式)
所以有dp[i][j] = max(dp[i][j] , (1式) ,(2式) ) ;
考虑每次枚举k的话,复杂度是n*m*m 肯定会超时,所以像一个不用枚举k 的方法——单调队列优化dp
根据转移方程1 dp[i+1][k] - sum[i+1][k] 和k 有关,则设F(K) = dp[i+1][k] - sum[i+1][k]  这样只要在向上转移的时候,只要在转移范围之内,并且维护下一行的F(k) 是一个单调队列,及永远是最大值在最后面,
现在的问题就是要预处理出每个点的转移范围,即对每一行的第i个位置的 t 相加,从0加到t,如果大于k则从1开始逐个递减,这样从前向后扫描一边,因为t肯定是正数所以扫描一遍即可预处理所有的左边界,
再从后向前扫描一边即可预处理出所有的右边界,然后用一个优先队列储存使得f(k)在转移范围内的从小到大的k值,则最后肯定是从这个k值转移到此状态是大的高兴值
 
这里注意一个小细节,就是一共有n+1行
 
 代码:
 #include<cstdio>
#include<algorithm>
using namespace std;
#define N 104
#define M 10004 int L[N][M],R[N][M];
int v[N][M],t[N][M];
int n , m , k ;
int Q[M];
int f[M],sum[N][M],dp[N][M];
int main()
{
while(~scanf("%d %d %d",&n , &m , &k),n||m||k)
{
for(int i = ; i <= n+ ;i++)
for(int j = ; j < m ;j++)
scanf("%d",&v[i][j]);
for(int i = ; i <= n+ ; i++)
for(int j = ; j < m ;j++)
scanf("%d",&t[i][j]);
for(int i = ; i <= n+ ; i++)
{
sum[i][] = ;
for(int j = ; j <= m ;j++)
sum[i][j] = sum[i][j-] + v[i][j-];
}
for(int i = ; i <= n+ ; i++)
{
L[i][] = ;R[i][m] = m;
int cur = , id = ;
for(int j = ; j <= m ;j++){
cur+=t[i][j-];
while(cur>k) cur-=t[i][id++];
L[i][j] = id;
}
cur = ; id = m-;
for(int j = m- ; j>= ; j--){
cur+=t[i][j];
while(cur>k) cur -= t[i][id--];
R[i][j] = id+;
}
}
for(int i = ; i < m+ ; i++) dp[n+][i] = ;
for(int i = n ; i >= ; i--)
{
int head = , rear = ;
for(int j = ; j < m+ ; j++)
{
f[j] = dp[i+][j] - sum[i+][j];
while(rear < head && Q[rear] < L[i+][j]) rear++;
while(head > rear && f[j] >=f[Q[head-]]) head--;
Q[head++] = j;
dp[i][j] = max(dp[i+][j],sum[i+][j]+f[Q[rear]]);
}
head = , rear = ;
for(int j = m ; j>= ; j--)
{
f[j] = dp[i+][j] + sum[i+][j];
while(rear<head&&Q[rear]>R[i+][j]) rear++;
while(head>rear&&f[j]>=f[Q[head-]]) head--;
Q[head++] = j;
dp[i][j] = max(dp[i][j],f[Q[rear]]-sum[i+][j]);
}
}
int ans = ;
for(int i = ; i < m+ ;i++) ans = max(ans,dp[][i]);
printf("%d\n",ans);
}
return ;
}

Parade(单调队列优化dp)的更多相关文章

  1. LA 4327 Parade(单调队列优化dp)

    题目链接: 题目大意(摘自刘汝佳<<算法竞赛入门经典--训练指南>>):F城是由n+1条横向路和m+1条竖向路组成.你的任务是从最南边的路走到最北边的路,使得走过的路上的高兴值 ...

  2. 单调队列优化DP,多重背包

    单调队列优化DP:http://www.cnblogs.com/ka200812/archive/2012/07/11/2585950.html 单调队列优化多重背包:http://blog.csdn ...

  3. bzoj1855: [Scoi2010]股票交易--单调队列优化DP

    单调队列优化DP的模板题 不难列出DP方程: 对于买入的情况 由于dp[i][j]=max{dp[i-w-1][k]+k*Ap[i]-j*Ap[i]} AP[i]*j是固定的,在队列中维护dp[i-w ...

  4. hdu3401:单调队列优化dp

    第一个单调队列优化dp 写了半天,最后初始化搞错了还一直wa.. 题目大意: 炒股,总共 t 天,每天可以买入na[i]股,卖出nb[i]股,价钱分别为pa[i]和pb[i],最大同时拥有p股 且一次 ...

  5. BZOJ_3831_[Poi2014]Little Bird_单调队列优化DP

    BZOJ_3831_[Poi2014]Little Bird_单调队列优化DP Description 有一排n棵树,第i棵树的高度是Di. MHY要从第一棵树到第n棵树去找他的妹子玩. 如果MHY在 ...

  6. 【单调队列优化dp】 分组

    [单调队列优化dp] 分组 >>>>题目 [题目] 给定一行n个非负整数,现在你可以选择其中若干个数,但不能有连续k个数被选择.你的任务是使得选出的数字的和最大 [输入格式] ...

  7. [小明打联盟][斜率/单调队列 优化dp][背包]

    链接:https://ac.nowcoder.com/acm/problem/14553来源:牛客网 题目描述 小明很喜欢打游戏,现在已知一个新英雄即将推出,他同样拥有四个技能,其中三个小技能的释放时 ...

  8. 单调队列以及单调队列优化DP

    单调队列定义: 其实单调队列就是一种队列内的元素有单调性的队列,因为其单调性所以经常会被用来维护区间最值或者降低DP的维数已达到降维来减少空间及时间的目的. 单调队列的一般应用: 1.维护区间最值 2 ...

  9. BZOJ1791[Ioi2008]Island 岛屿 ——基环森林直径和+单调队列优化DP+树形DP

    题目描述 你将要游览一个有N个岛屿的公园.从每一个岛i出发,只建造一座桥.桥的长度以Li表示.公园内总共有N座桥.尽管每座桥由一个岛连到另一个岛,但每座桥均可以双向行走.同时,每一对这样的岛屿,都有一 ...

随机推荐

  1. [array] leetcode - 48. Rotate Image - Medium

    leetcode - 48. Rotate Image - Medium descrition You are given an n x n 2D matrix representing an ima ...

  2. 什么是WAL?

    在写完上一篇<Pull or Push>之后,原本计划这一片写<存储层设计>,但是临时改变主意了,想先写一篇介绍一下消息中间件最最基础也是最核心的部分:write-ahead ...

  3. <!--[if lte IE 8][endif] ]-->IE下判断IE版本的语句

    <!--[if lte IE 6]> <![endif]--> IE6及其以下版本可见 <!--[if lte IE 7]> <![endif]--> ...

  4. lesson - 1 aming

    一.  Linux是什么* 关于Linux历史(http://www.aminglinux.com/bbs/thread-6568-1-1.html  需要大家查查资了解,也可以看看5期的视频)* 发 ...

  5. Django学习日记01_环境搭建

    1. 使用Vagrant 创建ubuntu虚拟机: 首先安装vagrant,网上有比较多的方法,如:http://www.th7.cn/system/mac/201405/55421.shtml 我使 ...

  6. React学习之路(二)

    状态(state) 状态就是组件描述某种显示情况的数据,由组件自己设置和更改,也就是所组件自己维护,目的就是为了在不同状态下使组件的显示不同 在组件中只能通过getInitialState的钩子函数来 ...

  7. window64 PHP ffmpeg详解简单上手 音频amr转mp3

    从网上找了一大堆关于window 64 ffmpeg的信息,都是又长又不关键,让人难消化. 我只要简单的amr转MP3格式而已. 终于搞明白.自己总结了下! 希望能帮助到喜欢言简意赅,一眼上手的同学. ...

  8. 架构师之路->架构师思维的培养

    公司的CMS(综合赋码管理系统)是WINFORM的CS架构.这套系统的架构师换了3届,到现在已经几年没有架构师了.本来入职时,岗位目标就是这个“自动化架构师”. 后来和领导达成共识先争取成为储备架构师 ...

  9. C#wxpay和alipay

    wxpayapi using System; namespace EPayInterfaceApp { public class EPayInterfaceApp { /** * 提交被扫支付API ...

  10. 第三章:Python基础の函数和文件操作实战

    本課主題 Set 集合和操作实战 函数介紹和操作实战 参数的深入介绍和操作实战 format 函数操作实战 lambda 表达式介绍 文件操作函数介紹和操作实战 本周作业 Set 集合和操作实战 Se ...