# ABC189 C - Mandarin Orange
ABC189 C - Mandarin Orange
問題へのリンク
問題概要
次の3つの条件をすべて満たすような整数の組
1 \leq l \leq r \leq N 1 \leq x -
以上l 以下の全ての整数r について、i x \leq A_i
その後、
最大で何個のみかんを食べることができるか。
制約
ABC中の解答
制約が
(一方で普段
そこで計算コストで下げるために尺取法を実装してsampleがすべてACになって提出したけどこれは間違いだった。
例えば私の尺取法では 2 3 3 1 1 1 2 1
のような場合は 2 2 2
あるいは 3 3
が最大と判断され
6
が解となってしまうが実際には 1 1 1 1 1 1 1 1
の 8
が最大であるからだ。
そこで計算コストを下げるために二次元配列で
import sys
input = sys.stdin.buffer.readline
N = int(input())
A = list(map(int, input().split()))
cummin = [[0] * N for _ in range(N)]
for i in range(N):
cummin[i][i] = A[i]
for j in range(i + 1, N):
cummin[i][j] = min(cummin[i][j - 1], A[j])
ans = 0
for left in range(N):
for right in range(left, N):
x = cummin[left][right]
ans = max(ans, (right - left + 1) * x)
print(ans)
公式解法1
あれこれ無駄に考えてしまったが制約が
ただしPythonだと TLE
になるので PyPy3
で提出する必要がある。
import sys
input = sys.stdin.buffer.readline
N = int(input())
A = list(map(int, input().split()))
ans = 0
for left in range(N):
x = A[left]
for right in range(left, N):
x = min(x, A[right])
ans = max(ans, (right - left + 1) * x)
print(ans)
Pythonで提出したら TLE
他の解法1
公式の解説ページに
上の記事はすごいわかりやすく、また最大長方形のDPのアルゴリズムがめちゃくちゃかしこくてすごい感心してしまった。勉強のために記事を読んだ後に自分で実装してみた。最後に stacks
に残っている中身を処理するために A
に 0
を追加しているところがオシャレポイント。
from collections import deque
import sys
input = sys.stdin.buffer.readline
N = int(input())
A = list(map(int, input().split())) + [0]
ans = 0
stacks = deque([(A[0], 0)])
for i in range(1, len(A)):
if stacks[-1][0] < A[i]:
stacks.append((A[i], i))
continue
if stacks[-1][0] > A[i]:
while stacks and stacks[-1][0] >= A[i]:
h, j = stacks.pop()
ans = max(ans, h * (i - j))
stacks.append((A[i], j))
print(ans)
Discussion