原题链接;https://www.acwing.com/problem/content/1020/2N-1限制了我们每次只能向下走或者向右走。
需要特殊处理一下边界,数组从0开始存的,因此,我们需要限制第一行和第一列只能从一边走过来。
y总的代码比较懒惰,需要特判。它没有先全部初始化成正无穷。
#include<iostream>
#include<algorithm>
using namespace std;
const int N=110;
int w[N][N];
int f[N][N];
int main()
{
int n;
cin>>n;
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
scanf("%d", &w[i][j]);
//这个时候求的是最小值,需要处理边界,不能让他从边界外边转移而来
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
{
if(i==1 && j==1 ) f[i][j]=w[i][j];
else
{
f[i][j]=1e9;
if(i>1) f[i][j]=min(f[i][j],f[i-1][j]+w[i][j]);
if(j>1) f[i][j]=min(f[i][j],f[i][j-1]+w[i][j]);
}
}
cout<<f[n][n]<<endl;
return 0;
}
先全部初始化成正无穷,就不需要特判了。
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=110;
int w[N][N];
int f[N][N];
int main()
{
int n;
cin>>n;
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
scanf("%d", &w[i][j]);
//求的是最小值,先初始化成正无穷
memset(f, 0x3f, sizeof f);
f[1][1] = w[1][1];
//这个时候求的是最小值,需要处理边界,不能让他从边界外边转移而来
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
{
// // 不是第一行的话,才可以从上边过来
// if(i>1) f[i][j]=min(f[i][j],f[i-1][j]+w[i][j]);
// // 不是第一列的话,才可以从左边过来
// if(j>1) f[i][j]=min(f[i][j],f[i][j-1]+w[i][j]);
// // 其实,既然已经全部初始化成正无穷了,就不需要特判了
// // 边界也被初始化成正无穷了,肯定不会从边界走过来。
// f[i][j]=min(f[i][j],f[i-1][j]+w[i][j]);
// f[i][j]=min(f[i][j],f[i][j-1]+w[i][j]);
f[i][j] = min(min(f[i][j],f[i-1][j]+w[i][j]), f[i][j-1]+w[i][j]);
}
cout<<f[n][n]<<endl;
return 0;
}