一道比较简单的动态规划的题,求从第一列的任何位置 到达最后一列 和的最小值。
所以这个状态可以是 列,在每一列有三种决策,直行,右上,右下。DP[i][j] 表示在第i行,j列到达最后一列的最小支出。
那么有了状态,我们可以进行转移,DP[i][j] = min{DP[i + 1][j + 1],DP[i][j + 1],DP[i - 1][j + 1]} + a[i][j];(跟数字三角形差不多)
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #define INF 0x3f3f3f3f 6 #define REP(i,N) for(int i = 0;i < (N);i++) 7 #define REP1(i,be,en) for (int i = (be);i < (en);i++) 8 9 using namespace std; 10 11 int row,col; 12 int a[12][110]; 13 int dp[12][110]; 14 int Next[12][110]; 15 int main () { 16 freopen("1.txt","r",stdin); 17 while (cin >> row >> col) { 18 REP(i,row) REP(j,col) cin >> a[i][j]; 19 for (int j = col - 1;j >= 0;j--) { 20 REP(i,row) { 21 if (j == col - 1) { 22 dp[i][j] = a[i][j]; 23 }else { 24 int ROW[3] = {i - 1,i,i + 1}; 25 if (i == 0) ROW[0] = row - 1; 26 if (i == row - 1) ROW[2] = 0; 27 sort(ROW,ROW + 3); 28 int MIN = INF; 29 int ans = 0; 30 REP(k,3) { 31 ans = dp[ROW[k]][j + 1] + a[i][j]; 32 if (ans < MIN) { 33 MIN = ans; 34 Next[i][j] = ROW[k]; 35 } 36 } 37 dp[i][j] = MIN; 38 } 39 } 40 } 41 int MIN = INF; 42 int first = 0; 43 REP(i,row) { 44 if (dp[i][0] < MIN) { 45 first = i; 46 MIN = dp[i][0]; 47 } 48 } 49 cout << first + 1; 50 for (int i = Next[first][0],j = 1;j < col;i = Next[i][j],j++) { 51 cout << " " << i + 1; 52 } 53 cout << endl << MIN << endl; 54 } 55 }
时间: 2024-10-30 01:15:26