알파벳으로 이루어진 문자열을 숫자(1-26)로 암호화 해서 하나의 긴 숫자로 만든다. 이 때 숫자를 다시 알파벳으로 변환하여 해석할 경우, 해석 가능한 문자열의 경우의 수를 구해야 한다.
하나의 숫자로 이루어진 암호가 입력으로 주어졌을 때, 가능한 해석의 가짓수를 1000000으로 나눈 나머지를 출력한다.
접근
가장 기본적인 상황은 N개의 숫자가 있을 경우, 앞의 N-1개의 숫자에 N번째 수를 추가하는 경우와 N-2개의 숫자에 N-1번째 수와 N-2번째 수를 함께 추가하는 경우이다.
점화식 DP(N) = DP(N-1)+DP(N-2)
그러나 추가되는 숫자가 0이거나 27 이상일 경우를 예외 처리를 해야 한다.
풀이 과정
숫자를 문자열로 입력 받는다.
dp를 (코드 문자열의 길이+1)만큼 0으로 이루어진 배열로 초기화 한다.
*문자열의 길이가 1인데 입력이 0인 경우, 불가능한 암호이므로 0을 출력하고, 프로그램을 종료한다.
문자열의 길이가 1이고, 0 이 아닌 경우 1가지 경우가 가능하므로 1을 출력하고, 프로그램을 종료한다.
문자열의 길이가 2부터 문자열 N까지, dp[2]~dp[N]을 구해야 한다. 초기값으로 dp[0]=1, dp[1]=1을 설정한다. 평범한 상황에 dp[2]=dp[1]+dp[0]=2 이고, 특수 상황인 203 같은 경우도 20/3 으로만 해석이 가능한데 이것도 경우의 수가 1이라 편리를 위해 dp[0]도 1로 설정한다.
dp의 N번째 경우를 구할 경우, 예시로 …..3421 에서 1이 N번째 수일 때, 두 자리 수로 추가 할 수 있는 21, N-1번째 수 2, N번째 수 1을 모두 상수로 변환 후 변수에 저장한다.
만약에 0이 연속으로 두 번 있거나, 30같이 3/0 과 30같이 둘 다 해석이 불가능하다면, 불가능한 암호이므로 0을 출력하고 프로그램을 종료한다.
*만약에 51같이 26보다 크지만, 5/1 로는 해석이 가능한 경우는 dp[n]=dp[n-1]이 성립한다.
만약에 10 같이 26보다 작지만, 1/0 으로는 해석이 불가능한 경우는 dp[n]= dp[n-2]가 성립한다.
*만약에 2201 같은 경우는 2/20/1 같이 해석이 가능하다, 이 때 201 부분은 1가지 경우만 가능하므로, 06 같이 그전 수가 0인 경우는 dp[n]=dp[n-3]이 성립한다.
*그 외의 평범한 경우에는 dp[n]=(dp[n-1]+dp[n-2])%1000000 이 성립한다.
*dp 배열의 마지막인 dp[-1]을 출력한다.