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

C++で行列の各行から選んだ要素の合計を最大化する方法

この記事では、2次元行列 mat[][] が与えられたとき、C++を使って各行から条件を満たす要素を1つずつ選び、その合計を最大化するプログラムの作成方法を解説します。

問題の概要

行列の各行から1つずつ要素を選んで合計を求めます。ただし、現在の行で選ぶ要素は、直前の行で選んだ要素よりも大きい値でなければなりません。この条件を満たす要素の組み合わせの中で、合計が最大になるものを求め、条件を満たす選び方が存在しない場合は -1 を出力します。

具体例で問題を確認してみましょう。

入力

mat[][] = {{4, 6, 1},
{2, 5, 7},
{9, 1, 2}}

出力

22

説明

1行目 = 6
2行目 = 7
3行目 = 9
合計 = 6 + 7 + 9 = 22

解法のアプローチ

最もシンプルな解法は、行列の最終行から順に処理を進めることです。まず最終行で最大の数値を見つけて MaxSum に加算し、その後1行上へ移動して、「下の行で選んだ最大値よりも小さい数値」の中で最大のものを探します。この操作を最上行に到達するまで繰り返します。途中で条件を満たす数値が見つからなかった場合は、-1 を返します。

この手法の計算量は O(行数 × 列数) であり、行列全体を一度走査するだけで答えが得られるため、効率的な解法といえます。

実装例

以下は、この解法の動作を示すC++プログラムです。

#include <iostream>
using namespace std;
#define row 3
#define col 3

int RowMaxSum(int a[row][col]){
    int maxValLastRow = 10000;
    int maxSum = 0;
    for (int i = row - 1; i >= 0; i--){
        int maxNo = -1;
        for (int j = 0; j < col; j++)
            if (maxValLastRow > a[i][j] && a[i][j] > maxNo)
                maxNo = a[i][j];
        if (maxNo == -1)
            return -1;
        maxValLastRow = maxNo;
        maxSum += maxValLastRow;
    }
    return maxSum;
}
int main(){
    int a[3][3] = {{4, 6, 1},
                   {2, 5, 7},
                   {9, 1, 2}};
    cout<<"The maximum sum of elements from each row in the matrix is "<<RowMaxSum(a);
    return 0;
}

実行結果

The maximum sum of elements from each row in the matrix is 22

まとめ

本記事では、行列の下の行から順に「直前の行で選んだ値より小さい最大値」を貪欲法(グリーディ法)的に選んでいくことで、各行から1要素ずつ取り出した合計の最大値を求める方法を紹介しました。条件を満たせない場合は -1 を返すことで、解が存在しないケースにも対応できます。

  1. C++で行列の各行の最大要素を見つける方法

    プログラミングにおいて、行列(2次元配列)から特定の値を抽出する操作は、よく使われる基本テクニックのひとつです。今回は、与えられた行列の各行の最大要素を見つけて出力する方法を解説します。このタスクは非常にシンプルです。各行に対して暫定最大値をリセットし、行内の要素を順番に比較して最大値を求め、それを出力するだけです。それでは、理解を深めるために実際のコードを見てみましょう。アルゴリズムの流れ処理の手順は以下の通りです。各行について、その行の最初の要素を暫定最大値として設定します。2番目の要素から順に、暫定最大値と比較していきます。比較対象の要素が暫定最大値より大きければ、暫定最大値を更新します

  2. Pythonで行・列のビット反転により2進行列の最大合計を求めるプログラム

    問題概要2次元のバイナリ行列(各要素が0または1の行列)が与えられます。任意の行または列を選び、そのすべてのビットを反転(0を1に、1を0に変更)する操作を何度でも実行できます。各行を2進数として読み取ったとき、これらの数値の合計を最大化するには、どのように操作すべきでしょうか。具体例たとえば、次のような行列が入力されたとします。010001この場合の出力は 11 になります。2つの行をそれぞれ反転すると「101」と「110」になり、10進数では 5 + 6 = 11 となるためです。解法の考え方(貪欲法)合計を最大化する鍵は、大きい桁のビットを優先的に1にすることです。以下の2つの戦略を組み