C++でドミノとトロミノを使って2×nのボードを埋める配置の数を数えるプログラム
ここでは、ドミノ(2×1の長方形)とトロミノ(L字型)という2種類のピースを扱います。どちらのピースも、下図のように回転させて使用することができます。

整数 n が与えられたとき、これらのピースを組み合わせて 2×n のボードを余りなく完全に埋める配置が何通りあるかを求めます。タイル張りのルールでは、すべてのマスが必ずいずれかのピースで覆われている必要があります。
例えば入力が 3 の場合、出力は 5 になります。実際の配置例は以下の通りです(異なる文字は異なるピースを表しています)。
- [XYZ XXZ XYY XXY XYY]
- [XYZ YYZ XZZ XYY XXY]
解法のアプローチ:動的計画法
この問題は動的計画法(DP)を使うことで効率的に解けます。手順は以下の通りです。
- サイズ N+5 の配列 dp を用意し、初期値として dp[1] := 1、dp[2] := 2、dp[3] := 5 を設定する。
- i が 4 から N までの範囲で、次の漸化式を順に適用する。
dp[i] := 2 × dp[i−1] + dp[i−3] - 最後に dp[N] を答えとして返す。
この漸化式は、「完全に埋まった状態」と「角が1マスだけ欠けた状態」という2種類の局面を組み合わせることで導出できます。直前の状態にドミノを縦置き・横置きで追加するパターンと、3つ前の状態からトロミノ2枚で残りを埋めるパターンを数え上げると、上記の式が自然に得られます。計算量は時間・空間ともに O(N) であり、大きな n に対しても高速に動作します。
C++による実装例
#include <bits/stdc++.h>
using namespace std;
const int MOD = 1e9 + 7;
int add(int a, int b){
return ((a % MOD) + (b % MOD)) % MOD;
}
class Solution {
public:
int solve(int N) {
vector <int> dp(N + 5);
dp[1] = 1;
dp[2] = 2;
dp[3] = 5;
for(int i = 4; i <= N; i++){
dp[i] = add(2 * dp[i - 1], dp[i - 3]);
}
return dp[N];
}
};
int main(){
Solution ob;
cout << (ob.solve(3));
}
入力
3
出力
5
-
C++で数値の各桁を3と8のみに変換する方法
はじめにこのチュートリアルでは、与えられた整数の各桁を「3」と「8」のみで構成されるように変換するプログラムをC++で解説します。具体的には、ある整数が与えられたとき、次のいずれかの操作を用いてすべての桁を3または8に変換することを目標とします。数値全体に1を加算または減算する特定の桁を任意の数字に直接置き換えるアルゴリズムの考え方最もシンプルで効率的なアプローチは、各桁を1つずつ確認する方法です。ある桁が「3」でも「8」でもない場合、その桁を直接「3」または「8」に書き換えればよいため、その桁につき1回の操作が必要になります。つまり、最小操作回数 = 「3」でも「8」でもない桁の個数となりま
-
Pythonで3×nのボックスを2×1のドミノで埋める方法の数を数えるプログラム
数 n が与えられたとき、3 × n の長方形ブロックを 1 × 2 のドミノ(骨牌)で隙間なく埋める方法が何通りあるかを求めます。ドミノは必要に応じて縦にも横にも回転させて配置できます。答えが非常に大きな値になる可能性があるため、10^9 + 7 で割った余りを返します。 例えば、入力が n = 4 の場合、出力は 11 となります。 解き方のアプローチ この問題は動的計画法(DP)を使うことで効率的に解けます。まず重要なポイントとして、次のことが挙げられます。 n が奇数の場合: マスの総数は 3 × n となり奇数になります。しかし、各ドミノは必ず 2 マスを覆うため、奇数個のマスを埋