国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【題解 | 基礎(chǔ)動態(tài)規(guī)劃】:數(shù)字三角形

這篇具有很好參考價值的文章主要介紹了【題解 | 基礎(chǔ)動態(tài)規(guī)劃】:數(shù)字三角形。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

數(shù)字三角形

鏈接:[USACO1.5] [IOI1994]數(shù)字三角形 Number Triangles

題目描述

觀察下面的數(shù)字金字塔。

寫一個程序來查找從最高點到底部任意處結(jié)束的路徑,使路徑經(jīng)過數(shù)字的和最大。每一步可以走到左下方的點也可以到達右下方的點。

【題解 | 基礎(chǔ)動態(tài)規(guī)劃】:數(shù)字三角形,# 題解記錄,動態(tài)規(guī)劃,算法,java,C++

在上面的樣例中,從 7 → 3 → 8 → 7 → 5 7 \to 3 \to 8 \to 7 \to 5 73875 的路徑產(chǎn)生了最大權(quán)值。

輸入格式

第一個行一個正整數(shù) r r r ,表示行的數(shù)目。

后面每行為這個數(shù)字金字塔特定行包含的整數(shù)。

輸出格式

單獨的一行,包含那個可能得到的最大的和。

樣例 #1

樣例輸入 #1

5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5

樣例輸出 #1

30

提示

【數(shù)據(jù)范圍】
對于 100 % 100\% 100% 的數(shù)據(jù), 1 ≤ r ≤ 1000 1\le r \le 1000 1r1000,所有輸入在 [ 0 , 100 ] [0,100] [0,100] 范圍內(nèi)。

題目翻譯來自NOCOW。

USACO Training Section 1.5

IOI1994 Day1T1


參考代碼

這道題就是很裸的DP,也是很經(jīng)典的入門題。我們先用記憶化搜索寫一遍,再來寫DP。

(1)記憶化搜索

我們首先讀取金字塔的行數(shù) r 和每行的數(shù)字,并存儲在二維數(shù)組 triangle 中。然后,我們使用記憶化搜索的深度優(yōu)先搜索函數(shù) dfs 來計算從金字塔頂部到底部的最大路徑和。

dfs 函數(shù)中,如果已經(jīng)計算過當(dāng)前位置到底部的最大路徑和,我們直接返回結(jié)果;如果已經(jīng)到達最后一行,我們返回當(dāng)前值;否則,我們返回從當(dāng)前位置到底部的最大路徑和,并將結(jié)果存儲在記憶化搜索數(shù)組 memo 中,以便后續(xù)使用。

最后,我們輸出最大路徑和。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;

public class Main {
    // 快讀快寫
    public static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    public static StreamTokenizer in = new StreamTokenizer(br);
    public static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
    
    public static int[][] triangle;
    public static Integer[][] memo;  // 用于記憶化搜索的數(shù)組

    public static void main(String[] args) throws IOException {
        // 讀數(shù)據(jù)
        in.nextToken();
        int r = (int) in.nval;
        triangle = new int[r][];
        memo = new Integer[r][r];  // 初始化備忘錄
        for (int i = 0; i < r; i++) {
            triangle[i] = new int[i+1];
            for (int j = 0; j <= i; j++) {
                in.nextToken();
                triangle[i][j] = (int) in.nval;
            }
        }

        // 記憶化搜索
        int maxSum = dfs(0, 0, r);

        out.println(maxSum);
        out.flush();
        br.close();
        out.close();
    }

    public static int dfs(int i, int j, int r) {
        // 如果已經(jīng)計算過,直接返回結(jié)果
        if (memo[i][j] != null) {
            return memo[i][j];
        }
        // 如果已經(jīng)到達最后一行,返回當(dāng)前值
        if (i == r - 1) {
            return memo[i][j] = triangle[i][j];
        }
        // 否則,返回從當(dāng)前位置到底部的最大路徑和
        return memo[i][j] = triangle[i][j] + Math.max(dfs(i + 1, j, r), dfs(i + 1, j + 1, r));
    }
}

記憶化搜索是一種優(yōu)化技術(shù),主要用于優(yōu)化遞歸算法,避免重復(fù)計算相同的子問題。它的主要思路是將已經(jīng)計算過的子問題的結(jié)果存儲起來,當(dāng)再次遇到相同的子問題時,直接從存儲的結(jié)果中獲取,而不是重新計算。

(2)動態(tài)規(guī)劃

下面我們來看DP的解法:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;

public class Main {
	public static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	public static StreamTokenizer in = new StreamTokenizer(br);
	public static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));

    public static void main(String[] args) throws IOException {
    	// 讀數(shù)據(jù)
        in.nextToken();
        int r = (int) in.nval;
        int[][] triangle = new int[r][];
        for (int i = 0; i < r; i++) {
            triangle[i] = new int[i+1];
            for (int j = 0; j <= i; j++) {
                in.nextToken();
                triangle[i][j] = (int) in.nval;
            }
        }

        // 動態(tài)規(guī)劃
        int[][] dp = new int[r][r];
        dp[0][0] = triangle[0][0];
        for (int i = 1; i < r; i++) {
            for (int j = 0; j <= i; j++) {
                if (j == 0) {
                    dp[i][j] = dp[i-1][j] + triangle[i][j];
                } else if (j == i) {
                    dp[i][j] = dp[i-1][j-1] + triangle[i][j];
                } else {
                    dp[i][j] = Math.max(dp[i-1][j-1], dp[i-1][j]) + triangle[i][j];
                }
            }
        }

		// 篩選答案(找到最后一行每個位置的路徑和最大值)
        int maxSum = dp[r-1][0];
        for (int i = 1; i < r; i++) {
            maxSum = Math.max(maxSum, dp[r-1][i]);
        }

        out.println(maxSum);
        out.flush();
        br.close();
        out.close();
    }
}

首先,我們定義狀態(tài) dp[i][j],表示從金字塔頂部到第 i 行第 j 列的最大路徑和。

這里,ij 的范圍都是從 0 開始的。

然后,我們需要找出狀態(tài)轉(zhuǎn)移方程(其實就是分析有多少種可能性)。

對于每一個位置 (i, j),我們可以從其上方 (i-1, j) 或者左上方 (i-1, j-1) 移動過來。

因此,到達當(dāng)前位置的路徑和就是上方或者左上方的路徑和加上當(dāng)前位置的值,我們選擇其中的最大值作為當(dāng)前位置的路徑和。

具體來說,狀態(tài)轉(zhuǎn)移方程可以寫成如下形式:

  • 當(dāng) j == 0(即在每一行的最左邊)時,只能從上方移動過來,所以 dp[i][j] = dp[i-1][j] + triangle[i][j]
  • 當(dāng) j == i(即在每一行的最右邊)時,只能從左上方移動過來,所以 dp[i][j] = dp[i-1][j-1] + triangle[i][j]
  • 當(dāng) 0 < j < i 時,可以從上方或者左上方移動過來,所以 dp[i][j] = max(dp[i-1][j-1], dp[i-1][j]) + triangle[i][j]。

最后,我們返回最后一行中的最大值,即為可能得到的最大的和。

小結(jié)

動態(tài)規(guī)劃(DP)的本質(zhì)是對問題狀態(tài)的定義和狀態(tài)轉(zhuǎn)移方程的定義。動態(tài)規(guī)劃往往可以用來優(yōu)化具有重疊子問題的遞歸算法(跟記憶化搜索相似)。

遞歸算法的特點是自頂向下,從一個問題開始,分解為多個子問題來求解。而動態(tài)規(guī)劃則是自底向上,從最簡單的子問題開始,逐步解決更復(fù)雜的子問題,直到得到原問題的解。

因此,對于一個可以用動態(tài)規(guī)劃解決的問題,我們通常可以先嘗試用遞歸的方法解決,然后找出遞歸中的重疊子問題,再使用動態(tài)規(guī)劃的方法進行優(yōu)化,避免重復(fù)計算。

但是需要注意的是,雖然所有的動態(tài)規(guī)劃問題都可以從遞歸的角度來理解,但并不是所有的遞歸問題都可以用動態(tài)規(guī)劃來優(yōu)化。只有當(dāng)遞歸問題具有“重疊子問題”和“最優(yōu)子結(jié)構(gòu)”時,才能使用動態(tài)規(guī)劃進行優(yōu)化。文章來源地址http://www.zghlxwxcb.cn/news/detail-850549.html

到了這里,關(guān)于【題解 | 基礎(chǔ)動態(tài)規(guī)劃】:數(shù)字三角形的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 算法分析與設(shè)計-數(shù)字三角形問題(動態(tài)規(guī)劃)(通俗易懂,附源碼和圖解,含時間復(fù)雜度分析)(c++)

    算法分析與設(shè)計-數(shù)字三角形問題(動態(tài)規(guī)劃)(通俗易懂,附源碼和圖解,含時間復(fù)雜度分析)(c++)

    (一)題目 問題描述 給定一個由 n n n 行數(shù)字組成的數(shù)字三角形,如圖所示。 試設(shè)計一個算法,計算從三角形的頂至底的一條路徑,使該路徑經(jīng)過的數(shù)字總和最大。 算法設(shè)計 對于給定的由 n n n 行數(shù)字組成的數(shù)字三角形,計算從該三角形的頂至底的路徑經(jīng)過的數(shù)字和的最大值

    2023年04月10日
    瀏覽(29)
  • 力扣120. 三角形最小路徑和(Java 動態(tài)規(guī)劃)

    力扣120. 三角形最小路徑和(Java 動態(tài)規(guī)劃)

    Problem: 120. 三角形最小路徑和 Problem:64. 最小路徑和 本題目可以看作是在上述題目的基礎(chǔ)上改編而來,具體的思路: 1.記錄一個int類型的大小的 n 乘 n n乘n n 乘 n 的數(shù)組(其中 n n n 為數(shù)組triangle的行數(shù))用于記錄 每一個當(dāng)前階段的最小路徑和 2.大體上可以依據(jù)題意得出動態(tài)轉(zhuǎn)移

    2024年01月22日
    瀏覽(19)
  • 藍橋 卷“兔”來襲編程競賽專場-03破解三角形密碼 題解

    挑戰(zhàn)介紹 三角形密碼指的是將一串字符串按照正直角三角形的形狀排列,傳遞的信息隱藏在每一行的最后一個字符,然后將所有的行的最后一個字符依次連接,就是需要傳遞的信息。 例如加密后的字符串是:我們愛的是藍色的心橋 將加密字符串按照正直角三角形填充后如下

    2023年04月16日
    瀏覽(19)
  • 【數(shù)字三角形】

    【數(shù)字三角形】

    題目描述 上圖給出了一個數(shù)字三角形。從三角形的頂部到底部有很多條不同的路徑。對于每條路徑,把路徑上面的數(shù)加起來可以得到一個和,你的任務(wù)就是找到最大的和。 路徑上的每一步只能從一個數(shù)走到下一層和它最近的左邊的那個數(shù)或者右 邊的那個數(shù)。此外,向左下走

    2024年02月05日
    瀏覽(22)
  • 【數(shù)字三角形】(C++版)

    【數(shù)字三角形】(C++版)

    題目描述 上圖給出了一個數(shù)字三角形。從三角形的頂部到底部有很多條不同的路徑。對于每條路徑,把路徑上面的數(shù)加起來可以得到一個和,你的任務(wù)就是找到最大的和。 路徑上的每一步只能從一個數(shù)走到下一層和它最近的左邊的那個數(shù)或者右 邊的那個數(shù)。此外,向左下走

    2024年02月16日
    瀏覽(32)
  • AcWing 898. 數(shù)字三角形 (每日一題)

    AcWing 898. 數(shù)字三角形 (每日一題)

    像數(shù)組下標(biāo) 出現(xiàn) i-1 的,在循環(huán)的時候從 i=1 開始。 0x3f3f3f3f : 1061109567 Integer.MAX_VALUE : 2147483647 在選用 Integer.MAX_VALUE 時,很可能會出現(xiàn) 數(shù)據(jù)溢出 。 所以在用 Integer.MAX_VALUE 時 需要先取 MAX 再加 a[i][j]; 注:做 數(shù)字三角形 這題時, 初始化時需要注意一下邊界 。 由于我們 狀態(tài)計

    2024年02月11日
    瀏覽(23)
  • 數(shù)字三角形+包子湊數(shù)(藍橋杯JAVA解法)

    數(shù)字三角形+包子湊數(shù)(藍橋杯JAVA解法)

    題目描述 上圖給出了一個數(shù)字三角形。從三角形的頂部到底部有很多條不同的路徑。對于每條路徑,把路徑上面的數(shù)加起來可以得到一個和,你的任務(wù)就是找到最大的和(路徑上的每一步只可沿左斜線向下或右斜線向下走)。 輸入描述 輸入的第一行包含一個整數(shù)?N?(1≤N≤

    2024年02月01日
    瀏覽(18)
  • 藍橋杯第十一屆省賽——數(shù)字三角形(python組)

    藍橋杯第十一屆省賽——數(shù)字三角形(python組)

    題目:數(shù)字三角形 【問題描述】: 上圖給出了一個數(shù)字三角形。從三角形的頂部到底部有很多條不同的路徑。對于每條路徑,把路徑上面的數(shù)加起來可以得到一個和,你的任務(wù)就是找到最 大的和。 路徑上的每一步只能從一個數(shù)走到下一層和它最近的左邊的那個數(shù)或者右 邊

    2023年04月10日
    瀏覽(24)
  • 湘大 XTU OJ 1148 三角形 題解(非常詳細):根據(jù)題意樸素模擬+觀察樣例分析需要計算幾輪 具體到一般

    湘大 XTU OJ 1148 三角形 題解(非常詳細):根據(jù)題意樸素模擬+觀察樣例分析需要計算幾輪 具體到一般

    1148 三角形 題目描述 給一個序列, 按下面的方式進行三角形累加,求其和值 。 比如序列為 1,2,3,4,5 輸入 有多組樣例。每個樣例的第一行是一個整數(shù)N( 1≤N≤100 ),表示序列的大小, 如果N為0表示輸入結(jié)束。這個樣例不需要處理。 第二行是N個整數(shù),每個整數(shù)處于[0,100]之間。

    2024年02月13日
    瀏覽(32)
  • 【算法挨揍日記】day03——雙指針?biāo)惴╛有效三角形的個數(shù)、和為s的兩個數(shù)字

    【算法挨揍日記】day03——雙指針?biāo)惴╛有效三角形的個數(shù)、和為s的兩個數(shù)字

    ?? 611.?有效三角形的個數(shù) https://leetcode.cn/problems/valid-triangle-number/ 給定一個包含非負整數(shù)的數(shù)組? nums ?,返回其中可以組成三角形三條邊的三元組個數(shù)。 本題是一個關(guān)于三角形是否能成立的題目,首先我們假設(shè)三角形的三邊(a,b,c),我們要保證兩邊之和大于第三邊 ? ?題

    2024年02月12日
    瀏覽(22)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包