C++で方程式 x1 + x2 + … + xn = k の整数解の個数を求める方法
この記事では、方程式 x₁ + x₂ + … + xₙ = k を満たす整数解の個数を求める問題を取り上げます。組み合わせの公式を活用することで、すべての解を列挙することなく効率的に計算できます。
解の個数を求める公式
方程式の整数解は、次の2種類に分けて数えることができます。
- 非負整数解(0 以上の整数)の個数:C(n + k − 1, k)
- 正の整数解(1 以上の整数)の個数:C(k − 1, n − 1)
非負整数解の個数は「重複組合せ」(仕切りと玉の並べ方)の考え方から導かれます。また、正の整数解の個数は、各変数にあらかじめ 1 を割り当て、残りの k − n を自由に分配する場合の数として求まります。この2つを足し合わせたものが、求める答えになります。
具体例
入力
n = 4 k = 7
出力
140
n = 4、k = 7 の場合を見てみましょう。非負整数解の個数は C(10, 7) = 120、正の整数解の個数は C(6, 3) = 20 となります。したがって、合計は 120 + 20 = 140 です。
アルゴリズム
- 変数 n と k を初期化します。
- 非負整数解と正の整数解の個数を、それぞれ二項係数として計算します。
- 両者を加算します。
- 答えを出力して終了します。
C++ による実装
以下は、上記のアルゴリズムを C++ で実装した例です。階乗と二項係数を求める補助関数を用意しています。
#include <bits/stdc++.h>
using namespace std;
// 階乗を計算する関数
int factorial(int n) {
int product = 1;
for (int i = 2; i <= n; i++) {
product *= i;
}
return product;
}
// 二項係数 nCr を計算する関数
int nCr(int n, int r) {
return factorial(n) / (factorial(n - r) * factorial(r));
}
int main() {
int n = 4;
int k = 7;
// 非負整数解の個数と正の整数解の個数の和を出力
cout << nCr(n + k - 1, k) + nCr(k - 1, n - 1) << endl;
return 0;
}
実行結果
上記のコードを実行すると、次の出力が得られます。
140
-
C++で実装する!隣接する生徒の点数に基づくテディ配布数の最小化アルゴリズム
問題概要N人の生徒と、それぞれの生徒が取得した点数を表す配列が与えられます。学校はこれらの生徒にテディベアを賞品として配布することを決めました。しかし、学校はコストを抑えたいと考えているため、以下の制約条件を満たしながら、配布するテディの総数を最小化することを目標とします。すべての生徒は、少なくとも1つのテディを受け取る必要があります隣り合って座っている2人の生徒のうち、点数が高い方の生徒は、低い方の生徒よりも多くのテディを受け取る必要があります同じ点数を持つ2人の生徒は、異なる数のテディを受け取っても構いません具体例例として、生徒が3人おり、その点数が次の配列で表されている場合を考えます。a
-
C++のCHAR_BITとは?意味と使い方を解説
CHAR_BITは、char型が持つビット数を表すマクロです。C++では「limits.h」ヘッダーファイル(C++では<climits>)で宣言されており、一般的な環境では1バイトが8ビットであることを示します。このマクロを利用することで、移植性の高いコードを書くことができます。環境に依存せずにchar型のビット数を取得できるため、ビット演算やデータサイズの計算に役立ちます。CHAR_BITの使用例以下は、C++でCHAR_BITを使用したサンプルコードです。CHAR_BITとsizeofを組み合わせてint型の全ビット数を求め、整数値を2進数形式で出力しています。#includ