Uva_000013
To ensure that each grid only goes once, each row is directed from left to right and then from right to left to dp. The maximum value of dp can be obtained for each grid.
If recursion is used, f can be initialized to-INF, but note that dp is performed only when the current grid is not equal to-INF. Otherwise, if the next grid is a positive value, the path is-INF.
#include<stdio.h>
#include<string.h>
#define MAXN 80
#define MAXK 10
#define INF 0x3f3f3f3f
int N, K, a[MAXN][MAXN], f[MAXK][MAXN][MAXN], left[MAXK][MAXN], right[MAXK][MAXN];
int init()
{
int i, j;
scanf("%d%d", &N, &K);
if(!N && !K)
return 0;
for(i = 1; i <= N; i ++)
for(j = 1; j <= N; j ++)
scanf("%d", &a[i][j]);
return 1;
}
void solve()
{
int i, j, k, max = -INF;
for(i = 0; i <= K; i ++)
for(j = 1; j <= N; j ++)
for(k = 1; k <= N; k ++)
f[i][j][k] = -INF;
if(a[1][1] < 0)
f[1][1][1] = a[1][1];
else
f[0][1][1] = a[1][1];
for(i = 0; i <= K; i ++)
for(j = 1; j < N; j ++)
if(f[i][1][j] != -INF)
{
if(a[1][j + 1] < 0)
{
if(f[i][1][j] + a[1][j + 1] > f[i + 1][1][j + 1])
f[i + 1][1][j + 1] = f[i][1][j] + a[1][j + 1];
}
else if(f[i][1][j] + a[1][j + 1] > f[i][1][j + 1])
f[i][1][j + 1] = f[i][1][j] + a[1][j + 1];
}
for(k = 2; k <= N; k ++)
{
for(i = 0; i <= K; i ++)
for(j = 1; j <= N; j ++)
if(f[i][k - 1][j] != -INF)
{
if(a[k][j] < 0)
{
if(f[i][k - 1][j] + a[k][j] > f[i + 1][k][j])
f[i + 1][k][j] = f[i][k - 1][j] + a[k][j];
}
else if(f[i][k - 1][j] + a[k][j] > f[i][k][j])
f[i][k][j] = f[i][k - 1][j] + a[k][j];
}
for(i = 0; i <= K; i ++)
for(j = 1; j <= N; j ++)
left[i][j] = right[i][j] = f[i][k][j];
for(i = 0; i <= K; i ++)
for(j = 1; j < N; j ++)
if(left[i][j] != -INF)
{
if(a[k][j + 1] < 0)
{
if(left[i][j] + a[k][j + 1] > left[i + 1][j + 1])
left[i + 1][j + 1] = left[i][j] + a[k][j + 1];
}
else if(left[i][j] + a[k][j + 1] > left[i][j + 1])
left[i][j + 1] = left[i][j] + a[k][j + 1];
}
for(i = 0; i <= K; i ++)
for(j = N; j > 1; j --)
if(right[i][j] != -INF)
{
if(a[k][j - 1] < 0)
{
if(right[i][j] + a[k][j - 1] > right[i + 1][j - 1])
right[i + 1][j - 1] = right[i][j] + a[k][j - 1];
}
else if(right[i][j] + a[k][j - 1] > right[i][j - 1])
right[i][j - 1] = right[i][j] + a[k][j - 1];
}
for(i = 0; i <= K; i ++)
for(j = 1; j <= N; j ++)
f[i][k][j] = left[i][j] > right[i][j] ? left[i][j] : right[i][j];
}
for(i = 0; i <= K; i ++)
if(f[i][N][N] > max)
max = f[i][N][N];
if(max == -INF)
printf("impossible\n");
else
printf("%d\n", max);
}
int main()
{
int t = 0;
while(init())
{
printf("Case %d: ", ++ t);
solve();
}
return 0;
}