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; 
}


posted @ 2014-03-07 10:11  来自大山深处的菜鸟  阅读(149)  评论(0编辑  收藏  举报