DP
= 알약 한 조각 전체를 개, 쪼갠 반 조각이 개 있을 때 알약을 먹는 순서의 가지수
입력으로 들어오는 에 대해 을 출력하면 정답
알약이 든 통에서 매일 알약을 꺼낼 때 통에 한 조각 전체가 몇 개 있는지, 쪼갠 반 조각이 몇 개 있는지에 따라 꺼낼 수 있는 가지수가 나뉜다.
예를 들어 첫날에는 통에 쪼갠 반 조각이 없기 때문에 무조건 한 조각을 꺼내게 되고, 그 뒤에는 통에 들어있는 한 조각 전체와 쪼갠 반 조각의 개수에 따라 꺼낼 수 있는 조각이 한 조각 전체일지 쪼갠 반 조각일지 나뉘게 된다.
그리고 꺼낸 알약이 전체 한 조각이라면 반 조각을 쪼개 넣으므로, 어떤 알약을 꺼내는지에 따라 통에 든 알약의 개수가 나뉜다.
를 통에 알약 한 조각 전체가 개, 쪼갠 반 조각이 개 있을 때 알약을 먹는 순서의 가지수라고 정의하고, 이 상태에서 만약 꺼낸 알약이 한 조각 전체라면 통에서 한 조각 전체가 하나 빠지고 꺼낸 알약을 반으로 쪼개서 다시 통에 넣기 때문에 그 이후에 알약을 먹는 순서의 가지수가 이 된다. 만약 꺼낸 알약이 반 조각이라면 그냥 반 조각을 먹기 때문에 그 이후에 알약을 먹는 순서의 가지수는 이 된다.
따라서 점화식이 이 되게 되고 처음 통에 알약이 30개까지 있을 수 있고, 이 때 30개를 먹을 동안 모두 한조각 전체만 뽑아서 통에 쪼갠 반 조각이 30개가 남을 수 있기 때문에 w, h의 범위도 30까지이다.
이에 따라 dp 테이블에 값을 구하고 문제 조건에 맞게 출력하면 정답이다.
fun main(){
val br = System.`in`.bufferedReader()
val dp = Array(31){ LongArray(31) }
for(i in 0..30){
for(j in 0..30){
if(i == 0){
dp[i][j] = 1
} else {
if(j < 30){
dp[i][j] += dp[i - 1][j + 1]
}
if(j > 0){
dp[i][j] += dp[i][j - 1]
}
}
}
}
var t = br.readLine().toInt()
while(t != 0){
println(dp[t][0])
t = br.readLine().toInt()
}
}