题意:从第一行任意位置开始走到最后一行任意位置。只能向下向左向右走。输出一个最短的路径。
解法:DP。从下向上,每行正反遍历搞两次。输出路径的时候乱搞了一发dfs。
代码:
#include <iostream>
#include <cstring>
#include <stdio.h>
using namespace std;
int num[110][510];
int ans[110][510];
int N,M;
int fin(int a,int b)
{
if(a>=0&&a<=N-1&&b>=0&&b<=M-1)
return ans[a][b];
return 2000010000;
}
void dfs(int i,int j)
{
cout<<j+1<<endl;
if(i==N-1){
return; }
int a,b;
if(fin(i+1,j)<fin(i,j+1))
a=i+1,b=j;
else
a=i,b=j+1;
if(fin(a,b)>fin(i,j-1))
a=i,b=j-1;
dfs(a,b);
}
int main()
{
scanf("%d%d",&N,&M);
for(int i=0;i<N;i++)
for(int j=0;j<M;j++)
scanf("%d",&num[i][j]);
for(int i=0;i<M;i++)
ans[N-1][i]=num[N-1][i];
for(int i=N-2;i>=0;i--)
{
ans[i][0]=ans[i+1][0]+num[i][0];
for(int j=1;j<M;j++)
ans[i][j]=min(ans[i][j-1]+num[i][j],ans[i+1][j]+num[i][j]);
for(int j=M-2;j>=0;j--)
ans[i][j]=min(ans[i][j+1]+num[i][j],ans[i][j]);
}
int w=0;long long ma=1000000000000;
int i;
for(i=0;i<M;i++)
if(ma>ans[0][i]) {ma=ans[0][i],w=i;}
dfs(0,w);
return 0;
}