UVaLive 4327 | POJ 3926 - Parade (单调队列优化DP)

来源:互联网 发布:c#获取网页源码 编辑:程序博客网 时间:2024/04/30 00:55

Parade
Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 658 Accepted: 151

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

Beijing 2008

[Submit]   [Go Back]   [Status]   [Discuss]





题意:

F城由N+1个横向道路和M+1个竖向道路组成,你的任务是求出从最南边的路走到最北边,使得走过的路上的高兴值之和最大(高兴值可能为负数),同一段路不能经过两次,且不能从北往南走,另外,每条横向道路上所话的时间不能超过k


思路:

dp[i][j]表示到达这个点的最大高兴值,他可以通过他下面一行即i+1的所有点上来然后再过来(前提是过来的时间和不能超过k),即时间限制为k的最大值,很显然的可以用单调队列优化。


不过POJ上面C++会TLE,G++不会。



#include <cstdio>#include <iostream>#include <vector>#include <algorithm>#include <cstring>#include <string>#include <map>#include <cmath>#include <queue>#include <set>using namespace std;//#define WIN#ifdef WINtypedef __int64 LL;#define iform "%I64d"#define oform "%I64d\n"#define oform1 "%I64d"#elsetypedef long long LL;#define iform "%lld"#define oform "%lld\n"#define oform1 "%lld"#endif#define S64I(a) scanf(iform, &(a))#define P64I(a) printf(oform, (a))#define P64I1(a) printf(oform1, (a))#define REP(i, n) for(int (i)=0; (i)<n; (i)++)#define REP1(i, n) for(int (i)=1; (i)<=(n); (i)++)#define FOR(i, s, t) for(int (i)=(s); (i)<=(t); (i)++)const int INF = 0x3f3f3f3f;const double eps = 10e-9;const double PI = (4.0*atan(1.0));const int maxn = 100 + 20;const int maxm = 10000 + 20;int roadH[maxn][maxm];int roadT[maxn][maxm];LL dp[maxn][maxm];int Q[maxm*2];int sumH[maxm];int sumT[maxm];inline int getInt() {    int ret = 0, u = 1;    char c = getchar();    while(c != '-' && !('0' <= c && c <='9')) c = getchar();    if(c == '-') u = -1, c=getchar();    while('0' <= c && c <= '9') {        ret = ret * 10 + c - '0';        c = getchar();    }    return ret * u;}int main() {    int n, m, K;    std::ios::sync_with_stdio(false);    while(scanf("%d%d%d", &n, &m, &K) != EOF && (n || m || K)) {        for(int i=1; i<=n+1; i++) {            for(int j=1; j<=m; j++) {                roadH[i][j] = getInt();            }        }        for(int i=1; i<=n+1; i++) {            for(int j=1; j<=m; j++) {                roadT[i][j] = getInt();            }        }        memset(dp, 0, sizeof(dp));        for(int i=n+1; i>=1; i--) {            int head = 0, tail = 0;            sumH[1] = 0;            sumT[1] = 0;            for(int j=1; j<=m+1; j++) {                if(j > 1) {                    sumH[j] = sumH[j-1] + roadH[i][j-1];                    sumT[j] = sumT[j-1] + roadT[i][j-1];                }                while(head < tail && dp[i+1][Q[tail-1]] + sumH[j] - sumH[Q[tail-1]] < dp[i+1][j]) tail--;                Q[tail++] = j;                while(head < tail && sumT[j] - sumT[Q[head]] > K) head++;                dp[i][j] = max(dp[i][j], dp[i+1][Q[head]] + sumH[j] - sumH[Q[head]]);            }            head = 0, tail = 0;            sumH[1] = 0;            sumT[1] = 0;            for(int j=m+1; j>0; j--) {                if(j <= m) {                    sumH[j] = sumH[j+1] + roadH[i][j];                    sumT[j] = sumT[j+1] + roadT[i][j];                }                while(head < tail && dp[i+1][Q[tail-1]] + sumH[j] - sumH[Q[tail-1]] < dp[i+1][j]) tail--;                Q[tail++] = j;                while(head < tail && sumT[j] - sumT[Q[head]] > K) head++;                dp[i][j] = max(dp[i][j], dp[i+1][Q[head]] + sumH[j] - sumH[Q[head]]);            }        }        LL ans = 0;        for(int i=1; i<=m+1; i++) {            ans = max(ans, dp[1][i]);        }        P64I(ans);    }    return 0;}






0 0
原创粉丝点击