/* 题目是 有一个 m*n 的矩阵然后矩阵中的每个点有个权值 你从 第一列走到最后一列 然后输出最小权值的 路径 和最小权值,来个 倒的 dp[i][j]=min(dp[i+1][j+1],dp[i][j+1],dp[i-1][j+1])+w[i][j] */ #include <cstdio> #include <string.h> #include <iostream> using namespace std; int turn[11][3]; int map[15][105],dp[15][105]; int path[15][105]; int main() { int n,m,i,j,k; while(scanf("%d%d",&m,&n)==2){ for(i=1;i<=m;i++) { turn[i][0]=i-1; turn[i][1]=i; turn[i][2]=i+1; } turn[1][0]=1;turn[1][1]=2;turn[1][2]=m; if(m>1) {turn[m][0]=1;turn[m][1]=m-1;turn[m][2]=m;} memset(path,0,sizeof(path)); for(i=1;i<=m;i++) for(j=0;j<n;j++) {scanf("%d",&map[i][j]); dp[i][j]=2147483647;} for(i=1;i<=m;i++) dp[i][n-1]=map[i][n-1]; for(i=n-2;i>=0;i--) for(j=1;j<=m;j++) for(k=0;k<3;k++) if(turn[j][k]<=m){ int d=turn[j][k]; if(dp[j][i]>(dp[d][i+1]+map[j][i])){ dp[j][i]=(dp[d][i+1]+map[j][i]); path[j][i]=d; } } int min_v=2147483647,L; for(i=1;i<=m;i++) if(dp[i][0]<min_v){ min_v=dp[i][0];L=i; } printf("%d",L); for(i=0;i<n-1;i++){ printf(" %d",path[L][i]);L=path[L][i];} printf(" %d ",min_v); } return 0; }