uva116
这题是一道dp的水题,类似于数塔,从右向左倒着加上去,找到最小值,然后在从左到右输出路径。
#include"iostream" #include"stdio.h" #include"algorithm" #include"string.h" #include"string" #include"cmath" #include"queue" #include"stack" #include"map" using namespace std; const int mx=105; const int inf=1000000; int n,m; int maze[mx][mx]; int MIN(int a,int b,int c) { int d=a<b?a:b; return c<d?c:d; } void DP() { int i,j; for(j=m-1;j>=1;j--) { for(i=0;i<n;i++) { maze[i][j-1]+=MIN(maze[(i+n-1)%n][j],maze[i][j],maze[(i+1)%n][j]); } } } void OUTPUT() { int i,j,min_length=inf,path; for(i=0;i<n;i++) { if(maze[i][0]<min_length) { min_length=maze[i][0]; path=i; } } cout<<path+1; for(j=1;j<m;j++) { int r=path; int min_num=maze[path][j]; if(maze[(path+n-1)%n][j]==min_num) { if((path+n-1)%n<r) r=(path+n-1)%n; } else if(maze[(path+n-1)%n][j]<min_num) { min_num=maze[(path+n-1)%n][j]; r=(path+n-1)%n; } if(maze[(path+1)%n][j]==min_num) { if((path+1)%n<r) r=(path+1)%n; } else if(maze[(path+1)%n][j]<min_num) { r=(path+1)%n; min_num=maze[(path+1)%n][j]; } path=r; cout<<" "<<path+1; } cout<<endl<<min_length<<endl; } int main() { // freopen("E:\\in.txt","r",stdin); int i,j; while(scanf("%d%d",&n,&m)==2) { for(i=0;i<n;i++) { for(j=0;j<m;j++) { scanf("%d",&maze[i][j]); } } DP(); OUTPUT(); } return 0; }