hdu 2490 队列优化dp

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

2008 Asia Regional Beijing

类似于传统的走格子,不过加了一个横向限制条件,横着连续走的格子属性之和不可大于一个固定值,另外可以左右双向移动。

题目说是从下方走到上方,自然可以倒过来思考,用我们熟悉的从上至下递推,一开始用错了递推式: 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)间,可以完成。

类似的对另一个方向,倒序递推一遍就好了!

 1 #include <iostream>
 2 #include<algorithm>
 3 #include<stack>
 4 #include<cstdio>
 5 #include<queue>
 6 #include<cstring>
 7 #include<ctype.h>
 8 using namespace std;
 9 #define inf 0x3f3f3f3f
10 typedef long long LL;
11 const int MAX = 1005;
12 struct node {
13     int w, id ;
14     bool operator<(const node &tmp)const {
15         return w < tmp.w;
16     }
17 };
18 int f[105][10005];
19 int w[105][10005], p[105][10005];
20 int main()
21 {
22     int n, m, i, j, k;
23     while (scanf("%d%d%d", &n, &m, &k) == 3 && (n + m + k)) {
24         memset(f, 0, sizeof(f));
25         for (i = 1;i <= n + 1;++i)
26         {
27             w[i][1] = 0;
28             for (j = 2;j <= m + 1;++j)
29             {
30                 scanf("%d", &w[i][j]);
31                 w[i][j] += w[i][j - 1];
32             }
33         }
34         for (i = 1;i <= n + 1;++i)
35         {
36             p[i][1] = 0;
37             for (j = 2;j <= m + 1;++j)
38             {
39                 scanf("%d", &p[i][j]);
40                 p[i][j] += p[i][j - 1];
41             }
42         }
43         for (i = 1;i <= n + 1;++i)
44         {
45             priority_queue<node>Q;
46             for (j = 1;j <= m + 1;++j)
47             {
48                 Q.push(node{f[i-1][j]-w[i][j],j});
49                 while (!Q.empty() && p[i][j]-p[i][Q.top().id]>k)Q.pop();
50                 if (!Q.empty()) f[i][j] = Q.top().w + w[i][j];
51             }
52             priority_queue<node>P;
53             for (j = m + 1;j >= 1;--j)
54             {
55                 P.push(node{ f[i - 1][j] + w[i][j],j });
56                 while (!P.empty() && p[i][P.top().id] - p[i][j] > k)P.pop();
57                 if (!P.empty()) f[i][j] = max(f[i][j],P.top().w-w[i][j]);
58             }
59         }
60         int ans = 0;
61         for (i = 1;i <= m + 1;++i)
62             ans = max(ans, f[n + 1][i]);
63         printf("%d\n",ans );
64     }
65     return 0;
66 }
时间: 2024-12-08 20:55:50

hdu 2490 队列优化dp的相关文章

HDU 4122 Alice&#39;s mooncake shop 单调队列优化dp

Alice's mooncake shop Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=4122 Description The Mid-Autumn Festival, also known as the Moon Festival or Zhongqiu Festival is a popular harvest festival celebrated by Ch

Parade(单调队列优化dp)

题目连接: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 lik

Tyvj1305最大子序和(单调队列优化dp)

描述 输入一个长度为n的整数序列,从中找出一段不超过M的连续子序列,使得整个序列的和最大. 例如 1,-3,5,1,-2,3 当m=4时,S=5+1-2+3=7当m=2或m=3时,S=5+1=6 输入格式 第一行两个数n,m第二行有n个数,要求在n个数找到最大子序和 输出格式 一个数,数出他们的最大子序和 测试样例1 输入 6 4 1 -3 5 1 -2 3 输出 7 备注 数据范围:100%满足n,m<=300000 是不超过m,不是选m个!!!!! /* 单调队列优化dp 单调队列维护的是前

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-1][k]+k*Ap[i]的单调性即可 1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 const int maxn = 2010; 6 int

1855: [Scoi2010]股票交易[单调队列优化DP]

1855: [Scoi2010]股票交易 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1083  Solved: 519[Submit][Status][Discuss] Description 最近lxhgww又迷上了投资股票,通过一段时间的观察和学习,他总结出了股票行情的一些规律. 通过一段时间的观察,lxhgww预测到了未来T天内某只股票的走势,第i天的股票买入价为每股APi,第i天的股票卖出价为每股BPi(数据保证对于每个i,都有APi>=

BZOJ 1855 股票交易(单调队列优化DP)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1855 题意:最近lxhgww又迷上了投资股票, 通过一段时间的观察和学习,他总结出了股票行情的一些规律. 通过一段时间的观察,lxhgww预测到了未来T天内某只股票的走势,第i天的股票买入价为每股APi,第i天的股票卖出价为每股BPi(数据保证对于每 个i,都有APi>=BPi),但是每天不能无限制地交易,于是股票交易所规定第i天的一次买入至多只能购买ASi股,一次卖出至多只能卖出BS

【单调队列优化dp】uestc 594 我要长高

http://acm.uestc.edu.cn/#/problem/show/594 [AC] 1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn=5e4+2; 5 const int inf=0x3f3f3f3f; 6 int n,c; 7 int cur; 8 int dp[2][maxn]; 9 int q[maxn]; 10 int main() 11 { 1

洛谷P1725 琪露诺 单调队列优化 DP

洛谷P1725 琪露诺 单调队列优化 DP 题意:1--n 每个点都有一个权值,从当前点i可以到达i+l--i+r 之间的点, 动态规划 方程 为 f[ i ] = max(f[ i ],f[ k ] ) +a[ i ] i-r<=k<=i-l 然而这样复杂度 就为 n^2 因为相当于 dp 是在求 一段区间的最大值,而这个最大值就可以用O(n) 来维护 注意 这个O(n) 是均摊O(n) 即将所有固定区间长度的 最大值求出来 是 O(n)的这样就把复杂度降到 O(n) 级别了 1 #incl

bzoj1233: [Usaco2009Open]干草堆tower 单调队列优化dp

又是一道单调队列优化dp的题目 这道题呢 先要了解一个结论,在多种可行的堆叠方案中,至少有一种能使层数最高的方案同时使得底边最短.即底边最短的,层数一定最高. 这个是zkw大神得出的 我也不会证明来着 反正这样之后我们就可以得出正确的方法了 递推式 F[i]=min(sum[j-1]-sum[i-1])  j>i 且 sum[j-1]-sum[i-1]>=F[j] 易得在满足的条件下j当然是越小越好了嘛 而这样得出的方程又满足一定的单调性 这样调整之后队首就是我们要的答案啦 又对于转移条件 f