Blog 第一篇
一道经典题。
两个方法: ## 自底向上推出最优解:
用 dp [i][j] 表示从 (i,j) 开始的最优解,答案即为 dp [1][1]
状态转移方程: dp[i][j] = max(dp[i+1][j], dp[i+1][j+1]) +
map[i][j]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| #include <iostream> using namespace std; const int MR(1001); int map[MR][MR]; int dp[MR][MR]; int n; inline int dmax(const int& a,const int& b) { return (a>b ? a : b); } int main() { cin >> n; for(int i(1);i<=n;++i) for(int j(1);j<=i;++j) cin >> map[i][j]; for(int i(1);i<=n;++i) dp[n][i] = map[n][i]; for(int i(n-1);i>0;--i) for(int j(1);j<=n;++j) { dp[i][j] = map[i][j] + dmax(dp[i+1][j], dp[i+1][j+1]); } cout << dp[1][1]; return 0; }
|
自顶而下推出最优解:
用 dp [i][j] 表示以 (i,j) 结束的最优解,则最优解为最后一行中 dp 的最大值
状态转移方程: dp[i][j] = max(dp[i-1][j-1],dp[i-1][j]) +
map[i][j]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| using namespace std; const int Mn(1002); int dp[Mn][Mn];
int main() { int n; cin >> n; for(int i(1);i<=n;++i) for(int j(1);j<=i;++j) { int tn; cin >> tn; dp[i][j] = max(dp[i-1][j-1],dp[i-1][j]) + tn; } int max(0); for(int i(1);i<=n;++i) if(dp[n][i] > max) max = dp[n][i]; cout << max; return 0; }
|