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

【C++】LCMがNとなる相異なる数の最大和を求める方法

本記事では、整数Nが与えられたとき、最小公倍数(LCM)がNとなる相異なる数の組の中で、その総和が最大になる値を求めるプログラムをC++で作成します。

問題の概要

ここでの課題は、Nを最小公倍数(LCM)として持つ数の組み合わせの中から、和が最大になるものを見つけ出すことです。

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

入力

N = 10

出力

18

説明

LCMが10となる最大の和は 1 + 2 + 5 + 10 = 18

10を最小公倍数とする数の組み合わせはいくつか存在しますが(例:2と5、1と10など)、その中でも10のすべての約数 {1, 2, 5, 10} を使った場合に和が最大となり、答えは18になります。

解法のアプローチ

この問題に対するシンプルかつ効果的な解法は、「NをLCMにしたいなら、Nのすべての相異なる約数を選べばよい」という性質を利用することです。

なぜこれで正しいのかを整理してみます。

  • N自身も約数であるため、Nの約数全体の集合のLCMは必ずNになります。
  • 約数以外の数を追加するとLCMがNより大きくなってしまうため、使える数は約数のみに限られます。
  • したがって、すべての約数を足し合わせたものが最大の和(maxSum)となります。

実装では、1から√Nまで順に調べて約数を列挙します。i が N の約数であれば、ペアとなる約数 N/i も同時に加算します。i と N/i が等しい場合(完全平方数の場合)は二重カウントを避けるため、一度だけ加算します。この方法により、計算量はO(√N)に抑えられます。

実装例

上記の解法を示すサンプルプログラムです。

#include <iostream>
using namespace std;

int calcFactorSum(int N){
    int maxSum = 0;
    // √N まで調べて約数を列挙する
    for (int i = 1; i*i <= N; i++){
        if (N % i == 0) {
            if (i == (N/i))
                maxSum = maxSum + i; // 平方数の場合は1回だけ加算
            else
                maxSum = maxSum + i + (N/i); // 約数のペアを両方加算
        }
    }
    return maxSum;
}
int main(){
    int N = 42;
    cout<<"LCMが "<<N<<" となる相異なる数の最大和は "<<calcFactorSum(N);
    return 0;
}

出力

LCMが 42 となる相異なる数の最大和は 96

42の場合、約数は {1, 2, 3, 6, 7, 14, 21, 42} であり、その総和は 1+2+3+6+7+14+21+42 = 96 となります。確かに、これらの数のLCMは42であり、これ以上の和は達成できません。

まとめ

LCMがNとなる相異なる数の最大和は、Nの全約数の総和と一致します。約数を√Nまでのループで効率的に列挙すれば、O(√N)の計算量でこの問題を解くことができます。競技プログラミングや数学的アルゴリズムの学習において、約数の性質は非常に重要な基礎知識なので、ぜひ押さえておきましょう。

  1. C++で指定した合計値になる最大サイズの部分集合を求める方法

    問題文 N個の要素からなる配列と合計値が与えられたとき、要素の合計が指定された値と一致する「最大サイズの部分集合」のサイズを求める問題です。 例 入力配列が arr = { 2, 3, 5, 10 }、合計値が sum = 20 の場合、出力は 4 になります。 なぜなら、 2 + 3 + 5 + 10 = 20 となり、配列の全要素を選んだ部分集合の合計が指定された合計値と一致するためです。 アルゴリズム この問題は動的計画法(DP)を用いて効率的に解くことができます。 まず、通常の部分和問題と同様に subset[i][j] というブール型のDPテーブルを用意します。これは「最初の j

  2. C++で醜い数(アグリー・ナンバー)のみを含む部分配列の最大長を求める方法

    問題の概要 N個の要素を持つ配列 arr[] が与えられます(0 ≤ arr[i] ≤ 1000)。この問題では、醜い数(アグリー・ナンバー)のみを含む部分配列(サブ配列)の最大長を求めることが求められます。 醜い数とは、素因数が 2、3、5 のみである数のことを指します。それ以外の素因数(7、11、13など)を含む数は醜い数とはみなされません。 例えば、醜い数の数列は次のようになります。 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, … 具体例 入力配列が {1, 2, 7, 9, 120, 810, 374} の場合、答えは 3 となります。 これは、醜い数のみ