单点时限: 2.0 sec
内存限制: 512 MB
问题描述
输入格式
输出格式
样例:
问题分析:
提示:
要到达A[M-1][N-1],路径上前面一个点只能是A[M-1][N-2]或A[M-2][N-1]
可以先计算A[0][0]到A[M-1][N-2]和A[M-2][N-1]的最短路径,选一个最短的
记录移动到A[i][j]的最后一次移动方向,通过回溯可以输出整条最短 路径
对每个A[i][j]:
存储从A[0][0]到A[i][j]的最短路径长度
还需要存储A[0][0]到达A[i][j]的最短路径上最后一次移动的方向
注意点:空间代替时间
考察点:递归
代码解决部分:
#include<stdio.h>
#include<string.h>
#define SIZE 200
typedef struct{int val;char dir}Elem;
void shortestpath(Elem A[][SIZE],int M,int N) //计算到达每个位置的最短路径长度
{
int i,j;
for(i=1;i<M;i++)
{
A[i][0].val += A[i-1][0].val;
A[i][0].dir = 'D';
}
for(i=1;i<N;i++)
{
A[0][i].val += A[0][i-1].val;
A[0][i].dir = 'R';
}
for(i=1;i<M;i++)
for(j=1;j<N;j++)
{
if(A[i-1][j].val<A[i][j-1].val) //向下移动
{
A[i][j].val += A[i-1][j].val;
A[i][j].dir = 'D';
}
else //向右移动
{
A[i][j].val += A[i][j-1].val;
A[i][j].dir = 'R';
}
}
}
void outpath(Elem A[][SIZE],int r,int c) //递归输出到A[r][c]的最短路径
{
if(r==0 && c == 0) return;
if(A[r][c].dir == 'D')
{
outpath(A,r-1,c);
putchar('D');
}
else
{
outpath(A,r,c-1);
putchar('R');
}
}
int main()
{
Elem A[SIZE][SIZE];
int M,N;
int i,j;
scanf("%d %d",&M,&N);
for(i=0;i<M;i++)
for(j=0;j<N;j++)
{
scanf("%d",&A[i][j].val);
A[i][j].dir = 0;
}
shortestpath(A,M,N);
printf("%d\n",A[M-1][N-1].val);
outpath(A,M-1,N-1);
putchar('\n');
return 0;
}
解释: