DP
题意很简单, 直接DP就可以了, 打印路径的时候我是从后向前遍历,每次dp[i][j-1]< dp[i][j]时说明发生了最近一次的更新,记录下来然后i--,到上一个花瓶的放置情况。
1 /*Author :usedrose */ 2 /*Created Time :2015/7/25 13:48:40*/ 3 /*File Name :2.cpp*/ 4 #include <cstdio> 5 #include <iostream> 6 #include <algorithm> 7 #include <sstream> 8 #include <cstdlib> 9 #include <cstring> 10 #include <climits> 11 #include <vector> 12 #include <string> 13 #include <ctime> 14 #include <cmath> 15 #include <deque> 16 #include <queue> 17 #include <stack> 18 #include <set> 19 #include <map> 20 #define INF 0x3f3f3f3f 21 #define eps 1e-8 22 #define pi acos(-1.0) 23 #define MAXN 110 24 #define OK cout << "ok" << endl; 25 #define o(a) cout << #a << " = " << a << endl 26 #define o1(a,b) cout << #a << " = " << a << " " << #b << " = " << b << endl 27 using namespace std; 28 typedef long long LL; 29 30 int n, m; 31 int dp[MAXN][MAXN]; 32 int G[MAXN][MAXN]; 33 34 int main() 35 { 36 //freopen("data.in","r",stdin); 37 //freopen("data.out","w",stdout); 38 cin.tie(0); 39 ios::sync_with_stdio(false); 40 while (cin >> n >> m) { 41 for (int i = 1;i <= n; ++ i) 42 for (int j = 1;j <= m; ++ j) 43 cin >> G[i][j]; 44 for (int i = 0;i <= n; ++ i) 45 for (int j = 0;j <= m; ++ j) 46 dp[i][j] = -INF; 47 for (int i = 0;i <= m; ++ i) 48 dp[0][i] = 0; 49 for (int i = 1;i <= n; ++ i) 50 for (int j = 1;j <= m; ++ j) { 51 if (i == 1) 52 dp[i][j] = max(dp[i][j-1], G[i][j]); 53 else { 54 dp[i][j] = max(dp[i][j-1], dp[i-1][j-1] + G[i][j]); 55 } 56 } 57 cout << dp[n][m] << endl; 58 stack<int> stk; 59 int i = n; 60 for (int j = m;j >= 1;-- j) { 61 if (i == 0) break; 62 if (dp[i][j-1] < dp[i][j]) { 63 stk.push(j); 64 i--; 65 } 66 } 67 cout << stk.top(); 68 stk.pop(); 69 while (!stk.empty()) { 70 int t = stk.top(); 71 stk.pop(); 72 cout << " " << t; 73 } 74 cout << endl; 75 } 76 return 0; 77 }