**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;

}