对于每一层,从两头分别计算一遍就行。
#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<string.h>
using namespace std;
const long long inf=((long long)1<<63 - 1);
int path[105][505],a[105][505],M,N;
long long dp[105][505];
void print(int i,int j)
{
if(path[i][j]!=-2)
{
if(path[i][j]==-1) print(i,j-1);
else if(!path[i][j]) print(i-1,j);
else print(i,j+1);
printf("%d\n",j);
}
}
int main()
{
// freopen("test.txt","r",stdin);
scanf("%d%d",&M,&N);
for(int i=1;i<=M;i++)
for(int j=1;j<=N;j++)
scanf("%d",&a[i][j]);
for(int i=1;i<=N;i++) dp[0][i]=0,path[0][i]=-2;
for(int i=1;i<=M;i++) dp[i][0]=dp[i][N+1]=inf;
for(int i=1;i<=M;i++)
{
for(int j=1;j<=N;j++)
{
if(dp[i][j-1]<dp[i-1][j]) path[i][j]=-1;
else path[i][j]=0;
dp[i][j]=min(dp[i-1][j],dp[i][j-1])+a[i][j];
}
for(int j=N;j>=1;j--)
{
long long t=min(dp[i-1][j],dp[i][j+1])+a[i][j];
if(t<dp[i][j])
{
if(dp[i][j+1]<dp[i-1][j]) path[i][j]=1;
else path[i][j]=0;
dp[i][j]=t;
}
}
}
long long ans=inf,num;
for(int i=1;i<=N;i++)
if(dp[M][i]<ans) ans=dp[M][i],num=i;
print(M,num);
return 0;
}