70분
처음에는 DP 배열에 모든 최대가 될 수 있는 값과 최솟값도 저장해서 풀어보려고 했으나
a 배열의 길이가 1,000,000 이하이기에 시간복잡도, 공간복잡도를 다 어길 것 같았다.
먼저 찬스를 안쓰는 조건을 먼저 생각해보자
n번째 수를 5라고 잡아두고,
1~n-1의 최솟값과 n+1~l의 최솟값이 있을 때
즉 찬스를 안썼을 때 기준(n)이 찬스를 쓰거나 안쓰는 경우에 살아남는 경우는 "양쪽 보다 큰 경우가 아닌 경우"
그럼 다음으로 생각해야 될 경우의 수가 찬스를 이미 써서 못 쓰는 경우인데
위 경우에서 찬스를 써서 살아남은 경우가 1 5 6, 6 5 1 이다.
여기서 기억할 것은 찬스를 쓰면 그쪽 범위의 숫자는 무조건 커진다.
결국 뭐가 됐든 최솟값 기준 1 5 6 (또는 6 5 1) 형태라면 살아남는다.
결론적으로 min(a[:n]) > a[n] or min(a[n+1:]) > a[n] 이면 answer에 +1 해주면 된다.
단, a 배열이 1,000,000으로 길어서 단순 슬라이싱을 계속하면 시간초과가 뜨므로 미리 계산해둘 필요가 있다.
def solution(a):
l = len(a)
if l < 2:
return 1
answer = 2
# 0부터 i까지의 최솟값
start = [0 for _ in range(l)]
start[0] = a[0]
# i부터 l-1까지의 최솟값
end = [0 for _ in range(l)]
end[l-1] = a[-1]
for n in range(1, l):
start[n] = min(start[n-1], a[n])
end[l-n-1] = min(end[l-n], a[l-n-1])
for n in range(1, l-1):
if start[n-1] > a[n] or end[n+1] > a[n]:
answer += 1
return answer
DP 문제는 풀다보면 반례가 나올만한 복잡한 경우의 수는 배제해도 되는 경우가 많은 것 같다.
단 그 반례가 나오지 않음을 증명하려고 고민하다보면 시간이 30분은 훌쩍 넘어버리는 것이 문제인 것 같다.
40분
부분 합을 미리 다 구하는 것은 4,000,000번 계산이라 충분하다.
두 바구니 배열이 붙어있음을 이용해 k라는 기준을 0부터 올려가며 k에서 천천히 양쪽으로 확장시켜 숫자가 같으면 저장하는 방식으로 풀면 된다.
def solution(cookie):
answer = -1
l = len(cookie)
arr = [[0 for _ in range(l)] for _ in range(l)]
for n in range(l):
arr[n][n] = cookie[n]
for k in range(1, l):
for i in range(l-k):
arr[i][i+k] = arr[i+k][i+k] + arr[i][i+k-1]
print(arr)
for k in range(l-1):
# 첫째의 끝 번호를 k로 둔다. 둘째는 첫 번호를 k+1로 둔다.
## 첫째의 범위 증가 인덱스는 i, 둘째의 범위 증가 인덱스는 j다.
## arr[k-i][k]와 arr[k+1][k+1+j]를 비교하면서 i 또는 j를 증가시킨다.
# 만약 서로 같으면 answer에 저장한다.
# k-i가 0보다 작아지거나 k+1+j가 l 이상이 되면 끝낸다.
i = 0
j = 0
while True:
if k-i < 0 or k+1+j > l-1:
break
# 둘째가 더 많으면 i 증가
if arr[k-i][k] < arr[k+1][k+1+j]:
i += 1
# 첫째가 더 많으면 j 증가
elif arr[k-i][k] > arr[k+1][k+1+j]:
j += 1
# 같으면 저장
else:
answer = max(answer, arr[k-i][k])
i += 1
return answer if answer != -1 else 0
두 바구니 배열이 인접하다는 것을 모르고 처음에 count와 index를 활용해서 풀어보려고 했지만 너무 복잡해져서 힌트를 보게 되었다.
위 방법처럼 k를 다 돌려보면서 조사하는 것은 cookie 배열이 2,000까지가 최대라 가능했던 방법인 것 같다.