Pythonで幸せにできる顧客の最大人数を求めるプログラム
問題概要
同じ長さを持つ2つのリスト customers(毎分の来店者数)と mood(客の機嫌)、および整数 k が与えられます。毎分 i には customers[i] 人の客が店を訪れ、mood[i] = 1 のときはその客たちが幸せであること、mood[i] = 0 のときは悲しいことを表します。ここで、連続する長さ k の区間をひとつ選び、その間の mood をすべて 1 に変更できます。最終的に幸せにできる人数の最大値を求めましょう。
例として、入力が customers = [2, 3, 6, 6, 3]、mood = [1, 1, 0, 0, 0]、k = 2 の場合を考えてみます。mood[2] と mood[3] を 1 に変更すれば、2 + 3 + 6 + 6 = 17 人の客を幸せにできるため、答えは 17 になります。
解法の考え方
この問題は、累積和(プレフィックスサム)とスライディングウィンドウを組み合わせることで、O(n) という高速な計算量で解くことができます。手順は以下のとおりです。
nをmoodの長さとします。- 長さ
n + 1の累積和配列aを 0 で初期化します。 - 変数
sを 0 にします。 iを 0 からn - 1まで順に処理します。a[i + 1] = a[i]とします。mood[i]が 1(非ゼロ)の場合:sにcustomers[i]を加算します。- それ以外の場合(
mood[i]が 0):累積和配列側にa[i + 1]へcustomers[i]を加算します。
- 変数
dを 0 にします。 iをkからnまで動かしながら、dをdとa[i] - a[i - k]の最大値で更新します。これは、長さkの区間内に含まれる「悲しい客」の合計の最大値を求める操作です。s + dを返します。
つまり、「もともと幸せな客の総数 s」に、「長さ k の窓で救済できる悲しい客の最大人数 d」を足したものが答えになります。
実装例
以下は Python による実装例です。
def solve(customers, mood, k):
n = len(mood)
a = [0] * (n + 1)
s = 0
for i in range(n):
a[i + 1] = a[i]
if mood[i]:
s += customers[i]
else:
a[i + 1] += customers[i]
d = 0
for i in range(k, n + 1):
d = max(d, a[i] - a[i - k])
return s + d
customers = [2, 3, 6, 6, 3]
mood = [1, 1, 0, 0, 0]
k = 2
print(solve(customers, mood, k))
入力
[2, 3, 6, 6, 3], [1, 1, 0, 0, 0], 2
出力
17
計算量
どちらのループもデータを一度ずつ走査するだけなので、時間計算量は O(n)、追加で必要なメモリは累積和配列ぶんの O(n) です。全探索のように O(n × k) かかる実装と比べても非常に効率的であり、入力サイズが大きくなっても安定して動作します。
-
Pythonで解く:「a」と「b」の文字列から作成できるユニークな文字列の数を求めるアルゴリズム
「a」と「b」のみで構成された文字列 s があるとします。このとき、「a」はそのまま「a」のままでもよいし、「b」に変換してもかまいません。一方、「b」は一切変更できません。この条件のもとで、作成できるユニークな文字列の総数を求めるのが本問題の目的です。問題の例たとえば、入力が s = baab の場合、出力は 4 になります。これは、以下の4種類の文字列を作成できるためです。baab(元のまま)babbbbabbbbb解法のアプローチこの問題は非常にシンプルな数学的性質を利用して解けます。「a」はそれぞれ独立に「a」または「b」の2択を選べるため、文字列中の「a」の個数を n とすると、組み
-
【Python入門】3つの数値から最大値を求める方法
3つの数値 a、b、c が与えられたとき、その中で最も大きい要素(最大値)を見つけるのが今回の課題です。ここでは、Pythonのリストと組み込み関数 max() を使ったシンプルな方法を、初心者向けにわかりやすく解説します。 実行例 入力:a = 2, b = 4, c = 3 出力:4 アルゴリズム ステップ1:ユーザーから3つの数値を入力として受け取る。 ステップ2:3つの数値をリストに格納する。 ステップ3:max() 関数を使ってリスト内の最大値 max(lst) を求める。 ステップ4:最後に最大値を出力する。 サンプルコード def maximum(a, b, c):