1. 程式人生 > >hdu 2084 數塔 dp 動態規劃

hdu 2084 數塔 dp 動態規劃

lan 必須 次循環 AC 如果 sin set main turn

開始動態規劃的學習了,先是比較基礎的,很金典的數塔。附上題目鏈接 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; }

hdu 2084 數塔 dp 動態規劃