C言語で二項係数の最大値を求める方法を解説
正の整数 N が与えられたとき、すべての二項係数の中から最大となる係数項を求める問題について解説します。
二項係数とは
二項係数の列は次のように表されます。
nC0, nC1, nC2, …, nCr, …, nCn-2, nCn-1, nCn
この中で nCr の最大値を見つけるのが目的です。二項係数は以下の式で計算できます。
nCr = n! / (r! × (n − r)!)
入出力例
例1:N = 4 の場合
出力: 最大係数 = 6
説明:
- 4C0 = 1
- 4C1 = 4
- 4C2 = 6
- 4C3 = 4
- 4C4 = 1
この場合、最大の係数は 6 です。
例2:N = 5 の場合
出力: 最大係数 = 10
説明:
- 5C0 = 1
- 5C1 = 5
- 5C2 = 10
- 5C3 = 10
- 5C4 = 5
- 5C5 = 1
この場合、最大の係数は 10 です。
アルゴリズムの考え方(動的計画法)
このプログラムでは、パスカルの三角形を利用した動的計画法によって二項係数を効率的に計算します。手順は以下のとおりです。
- ユーザーから N の値を入力として受け取ります。
- 関数 maxCoeff(int n) は引数 n を受け取り、二次元配列 C[n+1][n+1] を使って各二項係数の値を格納します。
- 変数 min と max を 0 で初期化します。min は配列 C[][] を走査する範囲の上限、max は見つかった最大の係数値を保持するために使います。
- i = 0 から n までの for ループで配列 C[][] を初期化していきます。
- 内側の for ループでは、i と n のうち小さい方まで走査します。
- j == 0 または j == i のときは C[i][j] = 1 とし、それ以外はパスカルの法則に従って C[i][j] = C[i-1][j-1] + C[i-1][j] とします。
- すべての計算が終わったら、配列 C[][] の最終行を再度走査し、最大値を変数 max に保存します。
- 結果として max を返します。
C言語での実装例
#include <stdio.h>
int maxCoeff(int n){
int C[n+1][n+1];
int max=0,min=0;
// 二項係数の値を計算する
for (int i = 0; i <= n; i++){
min=i<n?i:n;
for (int j = 0; j <= min; j++){
if (j == 0 || j == i)
C[i][j] = 1;
else
C[i][j] = C[i-1][j-1] + C[i-1][j];
}
}
for (int i = 0; i <= n; i++){
max = max> C[n][i] ? max: C[n][i];
}
return max;
}
int main(){
int N = 3;
printf("Maximum Coefficient :%d", maxCoeff(N) );
return 0;
}実行結果
上記のコードを実行すると、次のような出力が得られます。
Maximum Coefficient: 3
計算量について
このアルゴリズムの時間計算量は O(n²)、空間計算量も O(n²) です。二項係数を階乗で直接計算する方法と比べ、大きな数のオーバーフローを抑えながら段階的に値を構築できる点がメリットです。なお、数学的な性質から最大の二項係数は必ず中央(r = n/2)付近に現れるため、nC⌊n/2⌋ のみを計算すればさらに効率化することも可能です。
-
Pythonで「最大消去値」を求めるプログラム ― スライディングウィンドウ法による解説
問題の概要 正の整数のみを含む配列 nums が与えられます。この中から要素がすべて一意(重複なし)である部分配列をちょうど1つ選んで「消去」し、その部分配列に含まれる要素の合計値をスコアとして得ます。求めたいのは、この操作で取得できるスコアの最大値です。 例えば、入力が nums = [6,3,2,3,6,3,2,3,6] の場合、出力は 11 になります。これは、最適な部分配列が [6,3,2] または [2,3,6] のいずれかであり、どちらも合計が 11 になるためです。 解き方のアプローチ:スライディングウィンドウ この問題はスライディングウィンドウ(尺取り法)を使うことで効率的に
-
Pythonで解く「最小値が最大となる経路」問題 ― ヒープを使った貪欲法アルゴリズム
R行C列の整数で構成される行列Aが与えられます。このとき、左上のセル [0, 0] を出発点とし、右下のセル [R-1, C-1] を終点とする経路の中から、「経路上のセルのうち最小の値」をスコアとしたとき、そのスコアが最大になる経路を見つけます。例えば、ある経路が 8 → 4 → 5 → 9 と辿るとき、経路上の最小値は 4 なので、この経路のスコアは 4 となります。経路は、現在いるセルから上下左右の4方向(北・東・南・西)にある未訪問セルへ移動することで伸ばしていきます。具体例次のようなグリッドを考えてみましょう。545126746オレンジ色で示されたセルが最適な経路です。この経路上の最