C++でn×mグリッドを塗る最小コストを求める方法
はじめに
本記事では、n×mグリッドを塗る際の最小コストを求めるプログラムをC++で実装する方法を解説します。
問題設定は以下の通りです。2つの整数 n と m が与えられ、n×m のグリッドを塗りつぶすことを考えます。このとき、1つのセルを塗るコストは「そのセルに隣接する、すでに塗られたセルの数」に等しいものとします。この条件下で、グリッド全体を塗るための最小コストを計算するのが our タスクです。
考え方
この問題は実はシンプルな数式で解くことができます。グリッドを塗る順序を工夫しても、隣接関係によるコストの合計は一定になるため、以下の式で求められます。
最小コスト = (n - 1) × m + (m - 1) × n
この式の意味を分解してみましょう。
- (n - 1) × m: 縦方向の隣接ペアの数。各列には (n - 1) 個の上下の隣接関係があり、それが m 列分あるためです。
- (m - 1) × n: 横方向の隣接ペアの数。各行には (m - 1) 個の左右の隣接関係があり、それが n 行分あるためです。
つまり、グリッド内のすべての隣接セルのペアを数え上げることで、塗るコストの総和が求まります。
実装例
以下に、上記のロジックを実装したC++プログラムを示します。
#include <bits/stdc++.h>
using namespace std;
// 最小コストを計算する関数
int calc_cost(int n, int m){
int cost = (n - 1) * m + (m - 1) * n;
return cost;
}
int main(){
int n = 4, m = 5;
cout << calc_cost(n, m);
return 0;
}出力結果
31
コードの解説
このプログラムでは、n = 4、m = 5 の場合を例に計算しています。
- 縦方向の隣接ペア:(4 - 1) × 5 = 15
- 横方向の隣接ペア:(5 - 1) × 4 = 16
- 合計:15 + 16 = 31
したがって、4×5 のグリッドを塗る最小コストは 31 となります。
計算量
このアルゴリズムは数式を1回評価するだけなので、時間計算量は O(1) です。グリッドのサイズが大きくなっても、瞬時に答えを求められる点が大きなメリットです。
まとめ
n×mグリッドを塗る最小コストは、隣接セルのペア数を数えることで (n - 1) × m + (m - 1) × n という定数時間の計算で求められることを解説しました。グリッド系の問題では、このように隣接関係を数式化できるケースが多いため、考え方として覚えておくと役立ちます。
-
C++で解く:N×3グリッドの塗り方の総数を求める動的計画法アルゴリズム
問題概要サイズが n × 3 のグリッドがあり、すべてのマスを赤・黄・緑の3色のうちちょうど1色で塗ることを考えます。ここで重要な制約として、隣り合うマス(上下・左右)同士は同じ色にできないというルールがあります。行数 n が与えられたとき、この条件を満たしながらグリッド全体を塗る方法が何通りあるかを求めます。答えは非常に大きな値になる可能性があるため、10^9 + 7 で割った余りを返してください。例えば、入力が 1 の場合、出力は 12 になります。解法のアプローチこの問題は、各行の塗り方を状態として管理する動的計画法(DP)で効率的に解けます。手順は以下のとおりです。法 m を 10^9
-
C++でN×3グリッドの塗り分け方法の数を求めるアルゴリズム
問題概要n × 3 のサイズのグリッドを考えます。各セルは赤・黄・緑の3色のうち、ちょうど1色で塗る必要があります。ただし、「隣接するセル同士は同じ色にできない」という制約があります。ここで言う隣接とは、上下または左右で直接接触しているセルのことです。グリッドの行数 n が与えられるので、このグリッドを条件を満たすように塗り分ける方法が全部で何通りあるかを求めます。答えは非常に大きな値になる可能性があるため、109 + 7 で割った余りを返してください。例えば、入力が n = 1 の場合、出力は 12 になります。解法のポイント:行のパターンを2種類に分類するこの問題を効率的に解く鍵は、1行ご