n人が横一列に並んでおり、区間[l, r]内で身長が非増加(a[i] ≥ a[i+1])になっている最長区間の長さを求める問題です。
def find_longest_decreasing_interval_dp_optimized(n: int, heights: list[int]) -> int:
"""
空間最適化版のDP解法
Args:
n (int): 人数
heights (list[int]): 各人の身長のリスト
Returns:
int: 最長の逆背の順区間の長さ
Time Complexity: O(n)
Space Complexity: O(1)
"""
if n == 0:
return 0
if n == 1:
return 1
max_length: int = 1 # 全体での最大長
current_dp: int = 1 # dp[i]に相当(現在位置での最長区間長)
for i in range(1, n):
if heights[i-1] >= heights[i]: # 非増加条件を満たす場合
current_dp += 1 # 前の区間を延長
else:
current_dp = 1 # 新しい区間開始
max_length = max(max_length, current_dp)
return max_length
| ステップ | i | heights[i-1] | heights[i] | 条件 | current_dp | max_length |
|---|
# 手法1: 基本DP(配列版)
def basic_dp(n: int, heights: list[int]) -> int:
dp = [1] * n # O(n)空間
for i in range(1, n):
if heights[i-1] >= heights[i]:
dp[i] = dp[i-1] + 1
else:
dp[i] = 1
return max(dp)
# 手法2: 空間最適化版(推奨)
def optimized_dp(n: int, heights: list[int]) -> int:
max_length, current_dp = 1, 1 # O(1)空間
for i in range(1, n):
if heights[i-1] >= heights[i]:
current_dp += 1
else:
current_dp = 1
max_length = max(max_length, current_dp)
return max_length
# 手法3: 全区間DP(参考用)
def all_intervals_dp(n: int, heights: list[int]) -> int:
dp = [[False] * n for _ in range(n)] # O(n²)空間
# 全区間を2重ループで確認 O(n²)時間
# ...