C++で級数 K^n + K^(n-1)・(K-1) + … + (K-1)^n の合計を求める方法
この問題では、2つの整数 k と n が与えられます。級数 K^n + (K^(n-1) × (K-1)^1) + (K^(n-2) × (K-1)^2) + … + (K-1)^n の合計を求めるプログラムを作成するのが課題です。
問題を理解するための例
まず、具体的な入力と出力を見てみましょう。
入力: n = 3, k = 4 出力: 175 説明: 級数の合計は以下の通りです。 = 4^3 + ((4^2)×(3^1)) + ((4^1)×(3^2)) + ((4^0)×(3^3)) = 64 + 48 + 36 + 27 = 175
解法1:forループを使う単純なアプローチ
最もシンプルな方法は、forループを使って級数の各項を順番に計算し、その値を合計に加算していくことです。
アルゴリズム
sum = 0 で初期化 ステップ1: i を 0 から n まで繰り返す ステップ1.1: sum += pow(k, n-i) * pow((k-1), i) で sum を更新 ステップ2: sum を返す
実装例
この解法の動作を示すプログラムは以下の通りです。
#include <iostream>
#include <math.h>
using namespace std;
int calcSeriesSum(int k, int n) {
int sum = 0;
for (int i = 0; i <= n; i++) {
int p = pow(k, n-i) * pow((k-1), i);
sum = sum + p;
}
return sum;
}
int main() {
int n = 4;
int K = 2;
cout<<"級数の合計は "<<calcSeriesSum(K, n);
}出力
級数の合計は 31
この解法は正しい結果を返しますが、各項を個別に計算して足し合わせるため、計算量は O(n) となり、n が大きくなると非効率です。
解法2:一般式を用いた効率的なアプローチ
より効率的な解法は、級数の合計を表す一般式(閉じた形式)を数学的に導出することです。
級数 K^n + (K^(n-1) × (K-1)^1) + (K^(n-2) × (K-1)^2) + … + (K-1)^n は等比数列です。 初項は k^n、公比は (k-1)/k となります。 sum = K^n + (K^(n-1) × (K-1)^1) + (K^(n-2) × (K-1)^2) + … + (K-1)^n sum = k^n × (1 + (k-1)/k + (k-1)^2/k^2 + … + (k-1)^n) sum = (k^n × (1 − ((k-1)^(n+1))/k^(n+1))) / (1 − ((k-1)/k)) sum = k^n × ((k^(n+1) − (k-1)^(n+1))/k^(n+1)) / ((k − (k-1))/k) sum = k^n × ((k^(n+1) − (k-1)^(n+1))/k^(n+1)) / (1/k) sum = k^n × ((k^(n+1) − (k-1)^(n+1))/k^(n+1)) × k sum = k^(n+1) − (k-1)^(n+1)
このように、級数の合計は k^(n+1) − (k−1)^(n+1) という非常にシンプルな式で表せます。これにより、ループによる反復処理が不要になり、たった1回の計算で答えを求められるようになります。
実装例
公式を利用した解法のプログラムは以下の通りです。
#include <iostream>
#include <math.h>
using namespace std;
int calcSeriesSum(int k, int n) {
return (pow(k, (n+1)) - pow((k-1), (n+1)));
}
int main() {
int n = 4;
int K = 2;
cout<<"級数の合計は "<<calcSeriesSum(K, n);
}出力
級数の合計は 31
まとめ
単純なループによる解法は O(n) の計算量が必要ですが、等比数列の和の公式から導出した k^(n+1) − (k−1)^(n+1) を使えば、反復処理なしに直接答えを計算でき、大幅に高速化できます。
注意: n や k が大きくなると、計算結果が int 型の範囲(約21億)を超える可能性があります。大きな入力を扱う場合は、戻り値や変数を long long 型に変更することをおすすめします。
-
C++でarr[i]*iの合計を最大化する方法
問題の概要N個の整数からなる配列が与えられます。配列の要素は自由に並べ替えることができます。そのうえで、Σarr[i] * i(i = 0, 1, 2, ... n-1)の最大値を求めるのが課題です。例えば、入力配列が {4, 1, 6, 2} の場合、要素を昇順に並べ替えることで最大値28が得られます。{1, 2, 4, 6} = (1 * 0) + (2 * 1) + (4 * 2) + (6 * 3) = 28アルゴリズムこの問題は、次の手順で解くことができます。配列を昇順にソートする配列を走査し、各要素にインデックスi(0, 1, 2, ..., n-1)を掛けて合計する合計値を返すな
-
C++で等差数列(算術級数)の和を求めるプログラム
初項「a」、公差「d」、項数「n」が与えられたとき、等差数列を生成し、その合計を計算するのが本プログラムの目的です。 等差数列(算術級数)とは 等差数列とは、隣り合う項の差が常に一定である数列のことです。数列の初項は「a」に固定され、項と項の間の共通の差(公差)は「d」で表されます。 数列は次のように表されます。 a, a + d, a + 2d, a + 3d, … 入力例と出力例 入力: a = 1.5, d = 0.5, n = 10 出力: 等差数列の合計は: 37.5 入力: a = 2.5, d = 1.5, n = 20 出力: 等差数列の合計は: 335 解き方のアプローチ