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): 1145    Accepted Submission(s): 527

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[i][j][k]=MAX{f[i-1][j][0],f[i-1][j][1],f[i][j-1][k]|f[i][j+1][k] },
我想用第三维表示行走的不同方向分别对应的最值,但是后来发现了是错误的!由于有这个限制,可能此格子最优解不能由相邻格子的最优解推导出来导致计算错误。
  但是显然每一行对应的格子一定是由上一行的格子推导而来的,有两种形式,一是由上面的格子下来后往左走到达,另一种就是往右走到达,显然我们可以分类讨论。
说一下向右到达的,f[i][j]=MAX{ f[i-1][k]+w[j]-w[k] | 1<=k<=j&&p[j]-p[k]<=K }
这个递推式中w[j]是已知的,对于f[i-1][k]-w[k],我们对他用优先队列维护一个最大值,对每一行从左至右递推,每次push一个f[i-1][j]+w[j]来保证 k<=j这个条件成立。
对于队首不满足当前格子的节点,显然对后面的格子更不会满足,直接pop掉即可。这样的渐进复杂度在O(n*m)间,可以完成。
类似的对另一个方向,倒序递推一遍就好了!
 #include <iostream>
#include<algorithm>
#include<stack>
#include<cstdio>
#include<queue>
#include<cstring>
#include<ctype.h>
using namespace std;
#define inf 0x3f3f3f3f
typedef long long LL;
const int MAX = ;
struct node {
int w, id ;
bool operator<(const node &tmp)const {
return w < tmp.w;
}
};
int f[][];
int w[][], p[][];
int main()
{
int n, m, i, j, k;
while (scanf("%d%d%d", &n, &m, &k) == && (n + m + k)) {
memset(f, , sizeof(f));
for (i = ;i <= n + ;++i)
{
w[i][] = ;
for (j = ;j <= m + ;++j)
{
scanf("%d", &w[i][j]);
w[i][j] += w[i][j - ];
}
}
for (i = ;i <= n + ;++i)
{
p[i][] = ;
for (j = ;j <= m + ;++j)
{
scanf("%d", &p[i][j]);
p[i][j] += p[i][j - ];
}
}
for (i = ;i <= n + ;++i)
{
priority_queue<node>Q;
for (j = ;j <= m + ;++j)
{
Q.push(node{f[i-][j]-w[i][j],j});
while (!Q.empty() && p[i][j]-p[i][Q.top().id]>k)Q.pop();
if (!Q.empty()) f[i][j] = Q.top().w + w[i][j];
}
priority_queue<node>P;
for (j = m + ;j >= ;--j)
{
P.push(node{ f[i - ][j] + w[i][j],j });
while (!P.empty() && p[i][P.top().id] - p[i][j] > k)P.pop();
if (!P.empty()) f[i][j] = max(f[i][j],P.top().w-w[i][j]);
}
}
int ans = ;
for (i = ;i <= m + ;++i)
ans = max(ans, f[n + ][i]);
printf("%d\n",ans );
}
return ;
}

最新文章

  1. Vue插件开发入门
  2. Git 取消跟踪已版本控制的文件
  3. 可靠UDP
  4. c#绘制表格
  5. python积累
  6. sql查找最小缺失值与重用被删除的键(转载)
  7. poj3101
  8. Swift Core Data 图片存储与读取Demo
  9. shell 中条件判断
  10. 输出A打头的字符串
  11. 51nod 区间中第K大的数
  12. thinkphp调试技巧
  13. TortoiseGit之配置密钥
  14. JS功能函数
  15. FileZilla 使用笔记
  16. 应用脚手架创建一个React项目
  17. Linux入门笔记
  18. jquery插件中找到好玩插件 http://www.jq22.com/
  19. 《Linux 性能及调优指南》2.3 监控工具
  20. 吴裕雄 04-mysql创建数据库

热门文章

  1. 洛谷 P3263 [JLOI2015]有意义的字符串
  2. Python打印一个等边三角形
  3. Ip-san 配置过程
  4. 2015.6.30 反弹的教训(想做T)
  5. iOS 设置 延迟执行 与 取消延迟执行 方法 以及对 run loop 初步认识
  6. Linux Shell基础 Shell基本知识
  7. springboot中Controller没有被扫描
  8. PHP面试题汇总一
  9. iOS清除缓存功能开发
  10. NSFetchedResultController与UITableView