BOJ 27480 Even Harder

BOJ 27480 Even Harder

문제 링크:

문제 내용

음이 아닌 정수로 이루어진 배열 a1,a2,,ana_1, a_2, \cdots, a_n이 주어집니다. 다음의 과정을 거쳐 1번 위치에서 nn번 위치로 이동하는 방법이 유일하도록 배열의 몇몇 값을 0으로 바꾸고자 할 때, 0으로 바꿔야 하는 수의 최소 개수를 구하세요. 두 가지 이동 방법에서 한 쪽에서 거쳐간 위치를 다른 쪽에서 거쳐가지 않는다면, 두 이동 방법을 서로 다르다고 합니다.

  • ii번 위치에서는 i+1i+1 이상 i+aii+a_i 이하의 위치로 이동할 수 있습니다.
  • aia_i가 0이면 더 이상 이동할 수 없습니다.

입력

첫 줄에는 테스트 케이스의 개수 tt가 주어집니다. (1t5001 \le t \le 500)

각 테스트 케이스에 대해, 첫 줄에는 배열의 길이 nn이 주어지고, 두 번째 줄에는 a1,,ana_1, \cdots, a_n이 주어집니다. (2n30002 \le n \le 3000, 0aini0 \le a_i \le n-i)

모든 입력에서 1번 위치에서 nn번 위치로 이동하는 방법은 하나 이상 존재하며, 하나의 입력 파일에서 모든 테스트 케이스의 nn의 합은 30003000 이하입니다.

출력

각 테스트 케이스에 대해 문제의 정답을 한 줄에 출력합니다.

문제 풀이

스포일러

DP를 다음과 같이 정의합니다.

  • f(i,j)f(i, j): ii번째에서 시작하여 nn번째에 도달하는 유일한 경로에서 ii 다음에 jj를 밟아야 할 때 ai+1,,ana_{i+1}, \cdots, a_n 중에서 0으로 바꾼 수의 최소 개수; 그러한 방법이 존재하지 않으면 \infty

그러면 다음과 같은 식을 만들 수 있습니다. 편의상 ii에서 도달 가능한 최대 지점 i+aii + a_ibib_i라고 합시다. [x][x]는 Iverson bracket으로, 조건 xx가 참이면 1, 아니면 0입니다.

  • bii+1b_i \ge i+1이라면, f(i,i+1)=minbi+1jbi+1f(i+1,j)f(i, i+1) = \min_{b_i + 1 \le j \le b_{i+1}} f(i+1, j). jj에서 다음으로 밟는 위치가 bib_i 이하이면 ii에서 바로 그 지점을 밟는 경로가 생기므로, 그 위치는 bib_i보다는 커야 합니다.
  • bii+2b_i \ge i+2이라면, f(i,i+2)=minbi+1jbi+2f(i+2,j)+[bi+1i+2]f(i, i+2) = \min_{b_i + 1 \le j \le b_{i+2}} f(i+2, j) + [b_{i+1} \ge i+2]. ii에서 i+2i+2로 갈 수 있다는 것은 i+1i+1로도 갈 수 있다는 것으로, i+1i+1에서 i+2i+2로 갈 수 있으면 추가 경로가 생기므로 ai+1a_{i+1}을 0으로 만들어서 끊어줘야 합니다.
  • bii+3b_i \ge i+3이라면, f(i,i+3)=minbi+1jbi+3f(i+3,j)+[bi+1i+3]+[bi+2i+3]f(i, i+3) = \min_{b_i + 1 \le j \le b_{i+3}} f(i+3, j) + [b_{i+1} \ge i+3] + [b_{i+2} \ge i+3]. 먼저 i+2i+2에서 i+3i+3으로 가는 경로는 반드시 끊어야 하고, 이제 i+1i+1에서 i+2i+2를 거쳐 i+3i+3으로 갈 수는 없으므로 i+1i+1에서 바로 i+3i+3으로 갈 수 있는지만 체크해서 끊어주면 됩니다.
  • 이를 일반화하면 다음의 식을 얻습니다. bii+kf(i,i+k)=minbi+1jbi+kf(i+k,j)+1j<k[bi+ji+k]b_i \ge i+k \Rightarrow f(i, i+k) = \min_{b_i + 1 \le j \le b_{i+k}} f(i+k, j) + \sum_{1 \le j < k} [b_{i+j} \ge i+k]
  • 이는 f(i,j)f(i, j)의 누적 min과 [bij][b_i \ge j]의 누적합을 이용하여 구할 수 있습니다.
  • 예외적으로 다음 목적지가 nn인 경우는 더 이상 갈 곳이 없으므로 f(i,n)=i+1j<n[bjn]f(i, n) = \sum_{i+1 \le j < n} [b_{j} \ge n]으로 구할 수 있습니다.
Last updated on