Meaning
F City consists of n+1 transverse road and m+1 Vertical Road. Your task is to go from the southernmost road to the northernmost road, making the joy and the greatest on the road (note that the happy value on a certain path can be negative). The same section of the road can not go through two times, and not from north to south. In addition, the time spent on each transverse road can not exceed K.
Ideas
The problem was not evaluated on UVA and LA, so it was evaluated on HDU and POJ.
The state of the problem is relatively easy to think, F (i, j) indicates the maximum value of walking to the J Point of Line I
For every point, you can come from the next line, or you can walk from the left, or you can come from the right.
Let L (i, j) represent the maximum value of line I from the left to the J Point, and R (I, j) represents the maximum value of the first line coming from the right.
can be obtained, F (i, j) = max{L (i,j), R (i, J), F (i+1, J)}
The key is to require L (I, J) and R (I, J)
Sum (i, j) represents the value of the first J section of line I
L (i, j) = max{F (i+1, K) + sum (i, J)-Sum (i, k) | 1<=k<=j && K go to J Total time <= k}
The transformation can become:
L (i, j) = max{F (i+1, K)-sum (i, k) | 1<=k<=j && K go to J Total time <= k} + sum (i, J)
So as long as a k is maintained, the value of f (i+1, K)-sum (i, k) is maximized, which can be maintained with a monotone queue.
The method of finding R (I, J) can also be the same as the L
Code
/**========================================== * This are a solution for ACM/ICPC problem * * @source: uva-1427 Parade * @au Thor:shuangde * @blog: blog.csdn.net/shuangde800 * @email: zengshuangde@gmail.com *================================== =========*/#include <iostream> #include <cstdio> #include <algorithm> #include <vector> #
Include <queue> #include <cmath> #include <cstring> #define MP make_pair using namespace std;
typedef pair<int, int >PII;
typedef long long Int64;
const int INF = 0X3F3F3F3F;
Const double PI = ACOs (-1.0);
const int MAXN = 10005;
int n, m, K;
int MAT[105][MAXN];
int T[105][MAXN];
int F[105][MAXN];
int L[MAXN], R[MAXN];
int SUMVAL[MAXN], SUMT[MAXN];
inline int getsum (int* sum, int i, int j) {return sum[i]-sum[j]; Read in acceleration inline int nextint () {char c = GetChar () while (!isdigit (c) && c!= '-') c = GetChar (); int sigma = 1; if (c=
= '-') {sigma =-1; c = GetChar ();} int x = 0; while (iSdigit (c)) {x = x*10+c-' 0 '; C=getchar ();} return x*sigma; int main () {while (~scanf ("%d%d%d", &n, &m, &k) && n+m+k) {for (int i = 1; I &l t;= n + 1;
++i) for (int j = 2; J <= m + 1; ++j) mat[i][j] = Nextint ();
for (int i = 1; I <= n + 1; ++i) for (int j = 2; J <= m + 1; ++j) t[i][j] = Nextint ();
Init memset (f[n+2], 0, sizeof (f[n+2)); for (int i = n + 1; I >= 1;-i) {deque<int>que;//From left to right sumval[0] = sumt[0] = 1; int front = 0, R
ear = 0;
for (int j = 1; J <= m + 1; ++j) {sumval[j] = Sumval[j-1] + mat[i][j]; Sumt[j] = Sumt[j-1] + t[i][j];
int tmp = F[I+1][J]-sumval[j];
while (!que.empty () && f[i+1][que.back ()]-sumval[que.back ()] <= tmp) que.pop_back ();
Que.push_back (j);
while (!que.empty () && getsum (SumT, J, Que.front ()) > K) que.pop_front ();
if (i < n + 1) l[j] = max (F[i+1][j], F[i+1][que.front ()]-sumval[que.front ()] + sumval[j]); else l[j] = max (-inF, Sumval[j]-Sumval[que.front ()]);
}//Clear while (!que.empty ()) Que.pop_back ();
From right to left//http://www.bianceng.cn sumval[m+2] = sumt[m+2] = 0;
for (int j = m + 2; J >= 2;--j) {sumval[j] = sumval[j+1] + mat[i][j]; Sumt[j] = sumt[j+1] + t[i][j];
int tmp = f[i+1][j-1]-sumval[j];
while (!que.empty () && f[i+1][que.back () -1]-sumval[que.back ()] <= tmp) que.pop_back ();
Que.push_back (j);
while (!que.empty () && getsum (SumT, J, Que.front ()) > K) que.pop_front ();
if (i < n + 1) r[j] = max (f[i+1][j-1], F[i+1][que.front ()-1]-sumval[que.front ()] + sumval[j]);
else r[j] = max (-inf, sumval[j]-Sumval[que.front ()));
F[I][J-1] = max (l[j-1], r[j]);
} int ans = 0;
for (int i = 1; I <= m +1; ++i) ans = max (ans, f[1][i]);
printf ("%dn", ans);
return 0; }