먼저 하나의 수열 B=(b1,b2,…,bm)에 대해 g(B)를 구하는 일반적인 DP를 생각하자.
dpi=max(dpi−1,dpi−2+bi)
로 둘 수 있다. 여기서 dpi는 앞 i개의 원소만 고려했을 때의 답이다.
이제
di=dpi−dpi−1
라고 정의하자. 그러면
di=dpi−dpi−1=max(dpi−1,dpi−2+bi)−dpi−1=max(0,bi−(dpi−1−dpi−2))=max(0,bi−di−1)
이다.
또한
dpm=d1+d2+⋯+dm
이다. 따라서 모든 부분수열에 대한 g(B)의 합은, 모든 부분수열에서 각 원소가 추가될 때 생기는 d값의 합과 같다.
중요한 점은 1≤Ai≤10이므로 모든 di도 0 이상 10 이하라는 것이다.
cnt[j]를 현재까지 본 원소들로 만들 수 있는 비어 있지 않은 부분수열 중, 마지막 d값이 j인 부분수열의 개수라고 하자.
새 원소 x=Ai를 처리할 때 새로 생기는 부분수열은 두 종류이다.
- x 하나만 고른 부분수열: 이때 마지막 d값은 x이다.
- 기존 부분수열 뒤에 x를 붙인 부분수열: 기존 마지막 d값이 j라면 새 마지막 d값은 max(0,x−j)이다.
새로 생긴 모든 부분수열의 마지막 d값은 전체 답에 한 번씩 더해져야 한다. 그러므로 새로 만든 상태를 add에 모으면서
ans+=add[d]⋅d
를 해 주면 된다.
그 후 cnt[d]에 add[d]를 더하면, 다음 원소를 처리할 때 사용할 수 있다.
상태 수는 0,1,…,10 총 11개뿐이므로 각 원소마다 O(11)에 처리할 수 있다.
시간 복잡도는 O(11N), 메모리 복잡도는 O(11)이다.