题目描述
给定一个 n * m 的矩阵 a,从左上角开始每次只能向右或者向下走,最后到达右下角的位置,路径上所有的数字累加起来就是路径和,输出所有的路径中最小的路径和。
输入描述:
第一行输入两个整数 n 和 m,表示矩阵的大小。
接下来 n 行每行 m 个整数表示矩阵。
输出描述:
输出一个整数表示答案。
示例1
输入
复制
4 4
1 3 5 9
8 1 3 4
5 0 6 1
8 8 4 0
输出
复制
12
备注:
1≤n,m≤2000
0≤ Aij ≤100
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
int arr[2007][2007];
long long dp[2007][2007];
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1; j<=m;j++)
scanf("%d",&arr[i][j]);
for(int i=1;i<=n;i++)
dp[i][1]=dp[i-1][1]+arr[i][1];
for(int i=1;i<=m;i++)
dp[1][i]=dp[1][i-1]+arr[1][i];
for(int i=2;i<=n;i++)
{
for(int j=2;j<=m;j++)
{
dp[i][j] = min (dp[i-1][j] , dp[i][j-1]) + arr[i][j] ;
}
}
cout<<dp[n][m]<<endl;
return 0;
}
滚动数组,优化空间很多,时间复杂度不变。
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
int arr[2007];
long long dp[2007];
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
for(int j=1; j<=m;j++)
{
scanf("%d",&arr[j]);
if( i==1 )
dp[j]=dp[j-1]+arr[j]; //初始化第一行的情况
else if( j==1 )
dp[j]=dp[j]+arr[j];//初始化第一列的情况
else
dp[j]=min( dp[j-1], dp[j] ) + arr[j];
}
}
cout<<dp[m]<<endl;
return 0;
}