小乐乐要下山(脑残动态规划记录路径)
哈尔滨理工大学OJ上的题目,水是很水,结果我做了好久,发现题中要循环输入,我也是醉了。
题目很简单但是心里不平衡决定发一下。
Description
上学的路总是那么艰辛,在小乐乐辛苦的出了家门之后,她才想起自己的家已经搬到山上了(睡的真迷糊)。下山的路同样十分艰难,不同的地方通行的难易程度也不同。如图所示,小乐乐现在在山顶上,她面前有两条路,每条路通往一个地点,每个地点有一个值,表示这个通行的难易程度。最底层的地点就是山脚了。大家知道,小乐乐好懒好懒的,她想知道怎么下山最省力?
Input
第一行一个整数n(1<n<500)
随后n行,第i+1行有i个数字
表示山上的路况
随后n行,第i+1行有i个数字
表示山上的路况
Output
输出从山顶到山脚最省力的路。(保证答案唯一)
Sample Input
3
1
2 5
5 6 3
Sample Output
1 2 5
Hint
输入的是一个三角形,每个点能走到下面那个点和下右那个点。
1 #include<stdio.h> 2 #include<math.h> 3 #include<string.h> 4 #include<iostream> 5 using namespace std; 6 int a[600][600]; 7 int dp[600][600]; 8 int n; 9 int dpit(int i,int j) 10 { 11 if(i==n) 12 return dp[i][j]=a[i][j]; 13 else 14 return dp[i][j]=a[i][j]+min(dpit(i+1,j),dpit(i+1,j+1)); 15 } 16 void print(int i,int j) 17 { 18 if(i>n) return ; 19 if(dp[i][j]>dp[i][j+1]) 20 { 21 printf("%d",a[i][j+1]); 22 if(i!=n) 23 printf(" "); 24 else 25 printf("\n"); 26 print(i+1,j+1); 27 } 28 else 29 { 30 printf("%d",a[i][j]); 31 if(i!=n) 32 printf(" "); 33 else 34 printf("\n"); 35 36 print(i+1,j); 37 } 38 } 39 int main() 40 { 41 while(~scanf("%d",&n)){ 42 for(int i=1; i<=n; i++) 43 for(int j=1; j<=i; j++) 44 scanf("%d",&a[i][j]); 45 memset(dp,0,sizeof(dp)); 46 //printf("%d",dp[1][1]); 47 //int ans=dpit(1,1); 48 for(int i=n; i>=1; i--) 49 for(int j=1; j<=i; j++) 50 { 51 if(i==n) 52 dp[i][j]=a[i][j]; 53 // printf("%d ",dp[i][j]);} 54 else 55 dp[i][j]=a[i][j]+min(dp[i+1][j],dp[i+1][j+1]); 56 // printf("%d %d %d i=%d j=%d\n",dp[i+1][j],dp[i+1][j+1],a[i][j],i,j); 57 /* printf("%d ",dp[i][j]);*/ 58 } 59 /*for(int i=1;i<=n;i++) 60 for(int j=1;j<=n;j++){ 61 printf("%3d",dp[i][j]); 62 if(j==n) 63 printf("\n"); 64 }*/ 65 printf("%d ",a[1][1]); 66 print(2,1); 67 } 68 }
本题要求记录路径,不如我们来找路径,反正已经把DP过程都保存了,所以根据状态转移方程我们就可以再次找到路径了,就是向着小的地方走。
动态规划路径输出方法有好多,我会一一学习。