c++ 動態規划(數塔)


c++ 動態規划(dp)

題目描述

觀察下面的數塔。寫一個程序查找從最高點到底部任意位置結束的路徑,使路徑經過數字的和最大。
每一步可以從當前點走到左下角的點,也可以到達右下角的點。

輸入

5
13
11 8
12 7 26
6 14 15 8 
12 7 13 24 11

輸出

86

AC代碼

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 505;
int dp[MAXN][MAXN],a[MAXN][MAXN];
int max(int a,int b)//max函數求兩個數字之間的最大值
{
    return a>b?a:b;
}
int main()
{
    int n;
    cin >> n;
    for (int i = 1;i <= n;i ++)//輸入
    {
        for (int j = 1;j <= i;j ++)
        {
            cin >> a[i][j];
        }
    }
    dp[1][1] = a[1][1];//把起點直接放在dp[]里面
    for (int i = 2;i <= n;i ++)
    {
        for (int j = 1;j <= i;j ++)
        {
            dp[i][j] = max(dp[i - 1][j - 1],dp[i - 1][j]) + a[i][j];//dp公式,原理是先走一步,然后掃描這個點的上一層的鄰接點看看哪個點的dp值最大,然后用最大值加上他本身
        }
    }
    int ans = 0;
    for (int i = 1;i <= n;i ++)
    {
        ans = max(ans,dp[n][i]);//ans的作用是在最底部的元素中找一個最大的dp,輸出
    }
    cout << ans << endl;
    return 0;
}

另外一種方法

#include <iostream>
#include <string>
#include <algorithm>//STL庫函數
using namespace std;
int main()
{
    int t,n,dp[105][105],a[105][105];
    cin >> t;//t組數據
    while (t --)//重復執行直到t組數據都處理完
    {
        cin >> n;//塔的層數
        for (int i = 1;i <= n;i ++)//輸入
        {
            for (int j = 1;j <= i;j ++)
            {
                cin >> a[i][j];//把塔轉化成數組
            }
        }
        memset(dp,0,sizeof(dp));//把dp的值初始化為0
        for (int i = 1;i <= n;i ++)//把a[]最后一行賦值到dp[],因為最后一行的dp[]就等於最后一行數本身
        {
            dp[n][i] = a[n][i];
        }
        for (int i = n - 1;i >= 1;i --)
        {
            for (int j = 1;j <= i;j ++)
            {
                dp[i][j] = max(dp[i + 1][j + 1],dp[i + 1][j]) + a[i][j];//dp公式,原理是掃描這個點的下一層的鄰接點看看哪個點的dp值最大,然后用最大值加上他本身,在把大的值選中
            }
        }
    }
    cout << dp[1][1] << endl;//輸出
    return 0;
}



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM