116
/*
题目是 有一个 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("\n%d\n",min_v);
}
return 0;
}

浙公网安备 33010602011771号