Official
B - 観光地選び / Choosing Tourist Spots Editorial by admin Editorial for printing
DeepSeek V3(計算量が不正確)概要
各観光地の評価値(お土産の満足度の中央値)が与えられ、最大K個の観光地を選んで評価値の合計を最大化する問題です。
考察
重要な観察点は以下の通りです: 1. 各観光地の評価値は、その観光地のお土産の満足度をソートした中央値として計算できます 2. 評価値が正の観光地だけを選ぶのが最適です(負の値を足すと合計が減少するため) 3. 評価値が大きい観光地から順に選ぶことで、合計を最大化できます
素朴なアプローチとして全ての組み合わせを試す方法がありますが、Nが最大100、Kが最大100なので、組み合わせの数が膨大になり現実的ではありません。代わりに、貪欲法を用いることで効率的に解くことができます。
アルゴリズム
- 各観光地について、お土産の満足度をソートし、中央値を計算する
- 得られた評価値を降順(大きい順)にソートする
- 上位K個の評価値のうち、正の値のみを合計する
- 途中で負の値が出たら、それ以降は合計しない(負の値を足すと合計が減少するため)
計算量
- 時間計算量: \(O(N \cdot C_i \log C_i)\)
- 各観光地でソートする処理が支配的(\(C_i \leq 99\))
- 空間計算量: \(O(N)\)
- 評価値を格納するための配列のみを使用
実装のポイント
中央値の計算では、\((C_i + 1)/2\) 番目の値を取得する(インデックスは0始まりなので-1する)
評価値が正のものだけを選ぶことで最適解が得られる
空入力の場合(観光地が0個)への対応を忘れない
ソースコード
def main():
import sys
data = sys.stdin.read().splitlines()
if not data:
print(0)
return
first_line = data[0].split()
N = int(first_line[0])
K = int(first_line[1])
attractions = []
index = 1
for i in range(N):
C = int(data[index]); index += 1
values = list(map(int, data[index].split())); index += 1
values.sort()
median_index = (C + 1) // 2 - 1
median = values[median_index]
attractions.append(median)
attractions.sort(reverse=True)
total = 0
for i in range(min(K, len(attractions))):
if attractions[i] > 0:
total += attractions[i]
else:
break
print(total)
if __name__ == "__main__":
main()
この解説は deepseekv3 によって生成されました。
posted:
last update: