C++
 Computer >> コンピューター >  >> プログラミング >> C++

C++で解く直角三角形の数字パスにおける最大合計の求め方

問題文

数字が直角三角形の形に配置されたデータが与えられます。三角形の頂点から底辺へ向かう経路の中で、通過する数字の合計が最大になるものを見つけてください。ただし、各経路では次の数字として「真下」または「右斜め下」のいずれかのマスを選んで移動します。

例

入力:
3
4 5
1 10 7

このとき、最大合計は 18 となります(3 + 5 + 10 の経路が最適)。

アルゴリズム

基本的な考え方は、「最終行の各マスで終わる経路の最大合計」をすべて求め、その中から最大値を答えとして返すというものです。

これらの合計は、一つ上の行にある2つのマス(左上・右上)を順に参照していくことで再帰的に計算できます。

しかし、同じ部分問題が何度も重複して計算されるため、動的計画法(DP)を活用することで、最終行の各マスで終わる最大合計を効率よく求めることができます。

C++実装例

#include<bits/stdc++.h>
using namespace std;
int maxSum(int tringle[][3], int n){
    if (n > 1) {
        tringle[1][1] = tringle[1][1] + tringle[0][0];
        tringle[1][0] = tringle[1][0] + tringle[0][0];
    }
    for(int i = 2; i < n; i++) {
        tringle[i][0] = tringle[i][0] + tringle[i-1][0];
        tringle[i][i] = tringle[i][i] + tringle[i-1][i-1];
        for (int j = 1; j < i; j++){
            if (tringle[i][j] + tringle[i-1][j-1] >= tringle[i][j] + tringle[i-1][j]) {
                tringle[i][j] = tringle[i][j] + tringle[i-1][j-1];
            } else {
                tringle[i][j] = tringle[i][j] + tringle[i-1][j];
            }
        }
    }
    int max = tringle[n - 1][0];
    for(int i = 1; i < n; i++) {
        if(max < tringle[n-1][i]) {
            max = tringle[n-1][i];
        }
    }
    return max;
}
int main(){
    int tringle[3][3] = {
        {3},
        {4,5},
        {1,10,7}
    };
    cout << "Maximum sum = " << maxSum(tringle, 3) << endl;
    return 0;
}

出力

上記のプログラムをコンパイルして実行すると、以下の出力が得られます。

Maximum sum = 18
  1. C++で直角二等辺三角形に収まる正方形の最大数を求める方法

    この記事では、底辺の長さが「s」である直角二等辺三角形の中に、一辺「a」の正方形を最大でいくつ収めることができるかを求める問題を解説します。二等辺三角形とは、少なくとも2つの等しい辺を持つ三角形のことです。 まず、具体例を使って何をすべきかを理解しましょう。 入力例 s=5, a=1 出力 10 説明 − 底辺に並べられる正方形の数は、「s を a で割って 1 を引く」ことで求められます。つまり、底辺の正方形の数 = 5/1 − 1 = 4 個です。 同様に、最下段に4つの正方形を配置すると、その上に底辺が (s−a) の新しい二等辺三角形ができます。同じ手順を繰り返すと3個、さらにその上

  2. C++で二分木における2つの葉ノード間の最大パス合計を求める方法

    問題の概要 この問題では、各ノードが値を持つ二分木が与えられます。私たちのタスクは、二分木における2つの葉ノード(リーフノード)間の最大パス合計を求めるプログラムを作成することです。 ここで求めるのは、値の合計が最大になるような、ある葉ノードから別の葉ノードへのパスです。この最大合計パスには、ルートノードが含まれる場合もあれば、含まれない場合もあります。 二分木(Binary Tree)とは、各ノードが最大2つの子ノードを持つことができる木構造のデータ構造です。それぞれの子ノードは「左の子(left child)」と「右の子(right child)」と呼ばれます。 具体例 以下のような二分木