-
문제 링크
-
사용 언어
C++
-
소스
#include <iostream> using namespace std; int k, n; long long C[128][64]; int main() { cin >> k >> n; for(int i = 1; i <= k+n; i++){ C[i][0] = 1; } for(int j = 1; j <= n; j++){ for(int i = 1; i <= k+n; i++){ C[i][j] = C[i-1][j-1] + C[i+1][j-1]; } } cout << C[k][n]; }
-
논리
만약 모든 경우의 수에 대해 n초 후 수면보다 밑인지 아닌지 판단하여 경우의 수를 센다면,
시간 복잡도는 O(2n)이다.
당연히 이런 알고리즘을 사용하면 시간초과 에러를 만나게 된다.
k, n일 때 살아남는 경우의 수를 C[k, n]이라 하자.
이 상황에서 물벼룩은 위 또는 아래로 이동할 수 있다.
위로 갔을 경우 살아남는 경우의 수는 C[k-1, n-1]이고
아래로 갔을 경우 살아남는 경우의 수는 C[k+1, n-1]이다.
즉, C[k, n] = C[k-1, n-1] + C[k+1, n-1] 임을 알 수 있다.
자 위와 같은 점화식을 통해 우리는 동적 프로그래밍을 사용하면 된다는 것을 알아냈다.
초기값으로 C[0, 0] = 0 그리고 C[i, 0]=1을 주도록 한다.
그 후, 위 코드와 같은 논리를 통해 C[k, n]의 값을 찾아낸다.
시간복잡도는 O(n*k) 이다.
참고로 표로 보면 아래와 같다. k=2, n=3에 대해 계산과정을 표로 나타내었다.
\[\begin{matrix} k\backslash n&0&1&2&3\\0&0&0&0&0\\1&1&1&2&3\\2&1&2&3&{\color{red}6}\\3&1&2&4&7\\4&1&2&4&8\\5&1&2&4&8 \end{matrix}\]