메모리: 15112 KB, 시간: 152 ms
다이나믹 프로그래밍
2024년 2월 13일 14:28:42
정수 4를 1, 2, 3의 합으로 나타내는 방법은 총 4가지가 있다. 합을 나타낼 때는 수를 1개 이상 사용해야 한다. 합을 이루고 있는 수의 순서만 다른 것은 같은 것으로 친다.
정수 n이 주어졌을 때, n을 1, 2, 3의 합으로 나타내는 방법의 수를 구하는 프로그램을 작성하시오.
첫째 줄에 테스트 케이스의 개수 T가 주어진다. 각 테스트 케이스는 한 줄로 이루어져 있고, 정수 n이 주어진다. n은 양수이며 10,000보다 작거나 같다.
각 테스트 케이스마다, n을 1, 2, 3의 합으로 나타내는 방법의 수를 출력한다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
static long[][] dp= new long[10001][4];
public static void main(String[] args) throws IOException {
BufferedReader br =new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
dp[1][1]=1;
dp[2][1]=1; dp[2][2]=1;
dp[3][1]=1; dp[3][2]=1; dp[3][3]=1;
for(int i=4; i<=10000; i++) {
dp[i][1]=1;
dp[i][2]=dp[i-2][1]+dp[i-2][2];
dp[i][3]=dp[i-3][1]+dp[i-3][2]+dp[i-3][3];
}
for(int i=0; i<n; i++) {
int t = Integer.parseInt(br.readLine());
long temp = dp[t][1]+dp[t][2]+dp[t][3];
System.out.println(temp);
}
}
}
점화식 (n>=4)
1. dp[n][1]=1 (dp[n-1][1]으로 써도 상관은 없다.)
2. dp[n][2]=dp[n-2][1]+dp[n-2][2]
3. dp[n][3]=dp[n-3][1]+dp[n-3][2]+dp[n-3][3]
n=4일 때를 예시로 들어보면 n=4 일 때 가질 수 있는 방법의 수는 4개이다.


n=4일 때 1으로만 만들 수 있는 방법의 수는 1개밖에 없다. (1+1+1+1)
어느 수든 1로만 이용해 만드는 방법의 수는 1개밖에 없다.
이를 점화식으로 하면 dp[n][1]=1 로 간단하게 나타낼 수도 있다.
n=3일 때 1로만 만들 수 있는 방법은 1+1+1인데, 이에 +1을 더해 n=4일 때 1+1+1+1로 만들 수 있기에 dp[4][1]=dp[3][1]으로 나타낼 수도 있다.

n=4일 때 2로 끝나는 방법의 수는 2개이다. (1+1+2, 2+2)
이는 n=2일 때에서 +2를 해준 것과 같다.
즉 dp[4][2]= dp[2][1]+dp[2][2]로 나타낼 수 있고
이는 점화식으로 dp[n][2] = dp[n-2][1]+dp[n-2][2] 라고 나타낼 수 있다.

n=4 일 때 3으로 만들 수 있는 방법의 수는 1개이다. (1+3)
이는 n=1일 때에서 +3을 더한 것과 같다.
하지만 이를 점화식으로 나타내면 dp[n][3] = dp[n-3][1]으로 나타내야 하는데 이렇게 짜면 예제부터 틀리게 된다.
그래서 n=6 일 경우로 예시를 들면 조금 더 편하다.
n=3 일 때 방법에서 +3 을 해주면 n=6일 때 방법에 포함될 수 있다.

dp[6][3] = dp[3][1]+dp[3][2]+dp[3][3] 이라고 볼 수 있다.
이를 점화식으로 쓰면 dp[n][3] = dp[n-3][1]+dp[n-3][2]+dp[n-3][3] 이다.
이렇게 점화식 3개를 모두 사용하면 정답을 구할 수 있다.
- dp[n][1]=1 (dp[n-1][1]으로 써도 상관은 없다.)
- dp[n][2]=dp[n-2][1]+dp[n-2][2]
- dp[n][3]=dp[n-3][1]+dp[n-3][2]+dp[n-3][3]