递推DP HDOJ 5092 Seam Carving

 

题目传送门

 1 /*  2  题意:从上到下,找最短路径,并输出路径  3  DP:类似数塔问题,上一行的三个方向更新dp,路径输出是关键  4 */  5 #include <cstdio>  6 #include <algorithm>  7 #include <iostream>  8 #include <cstring>  9 #include <cmath> 10 #include <string> 11 #include <vector> 12 #include <queue> 13 #include <map> 14 #include <set> 15 #include <ctime> 16 #include <cstdlib> 17 using namespace std; 18 19 const int MAXN = 1e2 + 10; 20 const int INF = 0x3f3f3f3f; 21 int a[MAXN][MAXN]; 22 int dp[MAXN][MAXN]; 23 int pre[MAXN][MAXN]; 24 25 void print(int x, int y) 26 { 27 if (x == 1) 28  { 29 printf ("%d", y); return ; 30  } 31 print (x - 1, pre[x][y]); 32 printf (" %d", y); 33 } 34 35 int main(void) //HDOJ 5092 Seam Carving 36 { 37 //freopen ("C.in", "r", stdin); 38 39 int n, m, t, cas = 0; 40 scanf ("%d", &t); 41 while (t--) 42  { 43 scanf ("%d%d", &n, &m); 44 for (int i=1; i<=n; ++i) 45 for (int j=1; j<=m; ++j) scanf ("%d", &a[i][j]); 46 memset (pre, 0, sizeof (pre)); 47 48 for (int i=2; i<=n; ++i) 49 for (int j=1; j<=m; ++j) dp[i][j] = INF; 50 for (int i=1; i<=m; ++i) dp[1][i] = a[1][i]; 51 52 for (int i=2; i<=n; ++i) 53  { 54 for (int j=m; j>=1; --j) 55  { 56 for (int k=1; k>=-1; --k) 57  { 58 if (j + k < 1 || j + k > m) continue; 59 if (dp[i][j] > dp[i-1][j+k] + a[i][j]) 60  { 61 dp[i][j] = dp[i-1][j+k] + a[i][j]; 62 pre[i][j] = j + k; 63  } 64  } 65  } 66  } 67 68 int k = m; int mn = dp[n][m]; 69 for (int i=m-1; i>=1; --i) 70  { 71 if (mn > dp[n][i]) {mn = dp[n][i]; k = i;} 72  } 73 74 printf ("Case %d\n", ++cas); 75  print (n, k); 76 puts (""); 77  } 78 79 return 0; 80 } 81 82 /* 83 Case 1 84 2 1 1 2 85 Case 2 86 3 2 1 1 2 1 87 */

 

你可能感兴趣的:(seam)