[#1654]部分数列の和
7045 ワード
❓ Question
📖 Before Start
この友達も探索で解決できるでしょう!そんな安易な考え.
最近はブルートフォスの問題を多く解いているので、何でも徹底的に探ろうという考えが生まれました.
今回の問題が存在するすべての状況の数を探索する結論を得,以下の設計を開始した.
✒️ Design Algorithm
今回の問題もきっと順番探索だと思いますが….あ.うん.
それぞれの長さの長い線があって、それらを一定の長さに切ったとき、何本の長い線が現れますか?
最終的に短くするとより多くの数の網線が現れ,長さと数をチェックし,探索を行った.
以下は筆者が問題を解く前に作成したアルゴリズム設計である.
K本のローカルネットワーク線を切断するには,N本のローカルネットワーク線を形成する.数量はN個以上に達することができる.
現在、K本のローカルエリアネットワークがありますが、長さはそれぞれ異なりますので、カットする必要があります.
K, N
は、スペースを基準として連続的に入力される.K개의 랜선에 대한 길이
はK個ずつ入力される.💻 Making Own Code
❌ Wrong Code
import sys
k, n = map(int, sys.stdin.readline().split())
data = [int(sys.stdin.readline()) for _ in range(k)]
max_length = 1
for length in range(1, min(data)+1):
count = 0
for line in data:
count += line // length
if count >= n:
if length > max_length:
max_length = length
else:
break
print(max_length)
しかし、このコードはタイムアウトを続け、壮絶な酸化を行った.PyPy3
に提出されても、上のコードはタイムアウトし続け、戻ってくると残ります.しかし、順番に値を検索しない場合、いったいどのようにして値を検出するのでしょうか.
こうして半日うろうろしてやっと結論が出たのは,バイナリ検索を用いて問題を解く方法である.
✅ Correct Code
import sys
k, n = map(int, sys.stdin.readline().split())
data = [int(sys.stdin.readline()) for _ in range(k)]
min_len, max_len = 1, max(data)
while min_len <= max_len:
mid_len, count = (min_len + max_len) // 2, 0
for line in data:
count += line
if count >= n:
min_len = mid_len + 1
else:
max_len = mid_len - 1
print(max_len)
バイナリ探索の概念は初めて知ったが,時間の複雑さが本当に大幅に減少したことは否定できない.上記の順序探索は,時間複雑度
O(n)
と比較して,バイナリ探索はO(logN)
である.これは,中間値に基づいてナビゲーション領域の半分を徐々に縮小する方法である.これはあまりにも人をだますのではないでしょうか.
皆さんも筆者の場合のように、間違いなく問題をよく解いてください.
Reference
この問題について([#1654]部分数列の和), 我々は、より多くの情報をここで見つけました https://velog.io/@rookieand/1654-부분수열의-합テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol