开始动态规划的学习了,先是比较基础的,很金典的数塔。附上题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=2084
这题的状态转移方程是 dp[i][j] = max(dp[i-1][j-1],dp[i-1][j]) + m[i][j]; (dp[i][j] 表示在第 i 层 第 j 列时的最大和) 。 然后一个双重循环,边能算出。当然可以用滚动数组。但是注意用滚动数组解题时,第二层循环 j 必须从大到小, 因为 状态转移方程 为 f [ j ] = max( f[ j-1 ], f[ j ] ) + m[ i ] [ j ]; 每次更新都要用到前面的 j - 1 所以如果从小开始,不就被更新了,不在是上次循环的值了。结果错误。
代码:
#include <bits/stdc++.h> using namespace std; /* hdu 2084 数塔 */ int m[101][101]; int dp[103][103]; int f[104]; int n; //二维数组版 void DP () { memset(dp,0,sizeof(dp)); dp[1][1] = m[1][1]; for (int i=1;i<=n;i++) { for (int j=1;j<=n;++j) { dp[i][j] = max(dp[i-1][j-1],dp[i-1][j]) + m[i][j]; } } int mx = 0; for (int j =1;j<=n;++j) if (dp[n][j] > mx) mx = dp[n][j]; cout << mx <<endl; } //滚动数组版 void d_p() { memset(f,0,sizeof(f)); int mx = 0; for (int i=1;i<=n;i++) { for (int j=n;j>=1;--j) { f[j] = max(f[j-1],f[j]) + m[i][j]; if (f[j] > mx) mx = f[j]; } } cout << mx <<endl; } int main () { int T; cin >> T; while (T--) { cin >> n; for (int i=1;i<=n;++i) { for (int j=1;j<=i;++j) { cin >>m[i][j]; } } d_p (); } return 0; }
原文:https://www.cnblogs.com/yuluoluo/p/8830271.html