hdu 2084 数塔 dp 动态规划

  开始动态规划的学习了,先是比较基础的,很经典的数塔。附上题目链接  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