UVA_116

    这个题目可以用记忆化搜索实现,由于矩阵中的数字不全为正,故可以把INF作为还没有搜索过的标记。由于要求字典序最小,所以分情况控制好搜索顺序即可。

#include<stdio.h>
#include<string.h>
#define INF 1000000000
int R, C, a[20][110], f[20][110], next[2200];
void init()
{
int i, j;
for(i = 0; i < R; i ++)
for(j = 0; j < C; j ++)
scanf("%d", &a[i][j]);
}
int dfs(int x, int y)
{
int i, j, k, newx, min;
if(f[x][y] != INF)
return f[x][y];
min = INF;
if(x == 0)
{
for(i = 0; i < 2; i ++)
{
if(x + i >= R)
break;
newx = x + i;
k = dfs(newx, y + 1);
if(k < min)
{
min = k;
next[x * C + y] = newx * C + y + 1;
}
}
newx = R - 1;
k = dfs(newx, y + 1);
if(k < min)
{
min = k;
next[x * C + y] = newx * C + y + 1;
}
}
else if(x == R - 1)
{
newx = 0;
k = dfs(newx, y + 1);
if(k < min)
{
min = k;
next[x * C + y] = newx * C + y + 1;
}
for(i = -1; i < 1; i ++)
{
newx = x + i;
k = dfs(newx, y + 1);
if(k < min)
{
min = k;
next[x * C + y] = newx * C + y + 1;
}
}
}
else
{
for(i = -1; i < 2; i ++)
{
newx = x + i;
k = dfs(newx, y + 1);
if(k < min)
{
min = k;
next[x * C + y] = newx * C + y + 1;
}
}
}
return f[x][y] = min + a[x][y];
}
void printresult(int z, int flag)
{
if(flag)
printf("");
else
flag = 1;
printf("%d", z / C + 1);
if(next[z] != -1)
printresult(next[z], flag);
}
void solve()
{
int i, j, k, min, z;
for(i = 0; i < R; i ++)
for(j = 0; j < C; j ++)
f[i][j] = INF;
memset(next, -1, sizeof(next));
for(i = 0; i < R; i ++)
f[i][C - 1] = a[i][C - 1];
min = INF;
for(i = 0; i < R; i ++)
{
k = dfs(i, 0);
if(k < min)
{
min = k;
z = i * C;
}
}
printresult(z, 0);
printf("\n");
printf("%d\n", min);
}
int main()
{
while(scanf("%d%d", &R, &C) == 2)
{
init();
solve();
}
return 0;
}


posted on 2011-11-03 20:09  Staginner  阅读(460)  评论(0编辑  收藏  举报