求解矩阵最小路径和
给定一个m行n列的矩阵,从左上角开始每次只能向右或者向下移动,最后到达右下角的位置,路径上的所有数字累加起来作为这条路径的路径和。如下面一个4行4列的矩阵:
1 3 5 9
8 1 3 4
5 0 6 1
8 8 4 0
1→3→1→0→6→1→0是所有路径和最小的
拆分任务,先实现将所有路径遍历一边,通过递归来实现。
#include<stdio.h>
#include<stdlib.h>
int const maxn=100;
int a[maxn][maxn];
int n,m;
int b[30],flag=0;
void dfs(int i,int j,int b[],int flag)
{
if(i==n-1&&j==m-1)
{
for(int h=0;h<flag;h++)
printf("%d->",b[h]);
printf("%d\n",a[n-1][m-1]);
return;
}
b[flag]=a[i][j];
flag++;
if(i+1<n)
dfs(i+1,j,b,flag);
if(j+1<m)
dfs(i,j+1,b,flag);
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
scanf("%d",&a[i][j]);
}
}
dfs(0,0,b,0);
system("pause");
return 0;
}
运行结果
接下来实现路径统计的功能,通过定义一个结构体数组来保存路径相关信息;
#include<stdio.h>
#include<stdlib.h>
int const maxn=100;
int a[maxn][maxn];
struct node
{
int total;//记录路径总值
int road[20];//记录路径具体值
int step;//记录共经过多少个点(包括起点和终点)
}Both[100];
int riv=0;
int n,m;
int b[30],flag=0;
void dfs(int i,int j,int b[],int flag)
{
if(i==n-1&&j==m-1)
{
for(int h=0;h<flag;h++)
{
Both[riv].road[h]=b[h];
Both[riv].total=Both[riv].total+b[h];
}
Both[riv].road[flag]=a[n-1][m-1];
Both[riv].total=Both[riv].total+a[n-1][m-1];
Both[riv].step=flag+1;
riv++;
return;
}
b[flag]=a[i][j];
flag++;
if(i+1<n)
dfs(i+1,j,b,flag);
if(j+1<m)
dfs(i,j+1,b,flag);
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
scanf("%d",&a[i][j]);
}
}
dfs(0,0,b,0);
for(int i=0;i<riv;i++)
{
for(int j=0;j<Both[i].step;j++)
{
if(j==Both[i].step-1)
printf("%d 路程权重为%d\n",Both[i].road[j],Both[i].total);
else
printf("%d->",Both[i].road[j]);
}
}
system("pause");
return 0;
}
运行结果如图;
接下来通过判断并输出最小值即可
#include<stdio.h>
#include<stdlib.h>
int const maxn=100;
int a[maxn][maxn];
struct node
{
int total;//记录路径总值
int road[20];//记录路径具体值
int step;//记录共经过多少个点(包括起点和终点)
}Both[100];
int riv=0;
int n,m;
int b[30],flag=0;
void dfs(int i,int j,int b[],int flag)
{
if(i==n-1&&j==m-1)
{
for(int h=0;h<flag;h++)
{
Both[riv].road[h]=b[h];
Both[riv].total=Both[riv].total+b[h];
}
Both[riv].road[flag]=a[n-1][m-1];
Both[riv].total=Both[riv].total+a[n-1][m-1];
Both[riv].step=flag+1;
riv++;
return;
}
b[flag]=a[i][j];
flag++;
if(i+1<n)
dfs(i+1,j,b,flag);
if(j+1<m)
dfs(i,j+1,b,flag);
}
int main()
{
int min[2]={0};//min[0]保存最小路径权重,min[1]保存Both最小路径权重的下标
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
scanf("%d",&a[i][j]);
}
}
dfs(0,0,b,0);
min[0]=Both[0].total;
for(int i=0;i<riv;i++)
{
if(Both[i].total<min[0])
{
min[0]=Both[i].total;
min[1]=i;
}
}
for(int j=0;j<Both[min[1]].step;j++)
{
if(j!=Both[min[1]].step-1)
printf("%d->",Both[min[1]].road[j]);
else
printf("%d",Both[min[1]].road[j]);
}
system("pause");
return 0;
}
运行结果: