https://www.acmicpc.net/problem/2758
#include <iostream>
#include <vector>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int t;
cin >> t;
while (t--) {
int n, m;
long long ans = 0;
cin >> n >> m;
//dp[i][j]: 마지막으로 선택한 수가 j인 i개의 로또 번호
vector<vector<long long>> dp(n + 1, vector<long long>(m + 1, 0));
for (int i = 1; i <= m; i++) {
dp[1][i] = 1;
}
for (int k = 2; k <= n; k++) {
for (int i = 1; i * 2 <= m; i++) {
for (int j = i * 2; j <= m; j++) {
dp[k][j] += dp[k - 1][i];
}
}
}
for (int i = 1; i <= m; i++) {
ans += dp[n][i];
}
cout << ans << '\n';
}
return 0;
}
1. 문제
선영이는 매주 엄청난 돈을 로또에 투자한다. 선영이가 하는 로또는 1부터 m까지 숫자 중에 n개의 수를 고르는 로또이다.
이렇게 열심히 로또를 하는데, 아직까지 한 번도 당첨되지 않은 이유는 수를 고를 때 각 숫자는 이전에 고른 수보다 적어도 2배가 되도록 고르기 때문이다.
예를 들어, n=4, m=10일 때, 선영이는 다음과 같이 고를 수 있다.
- 1 2 4 8
- 1 2 4 9
- 1 2 4 10
- 1 2 5 10
따라서 선영이는 로또를 4개 산다.
선영이는 돈이 엄청나게 많기 때문에, 수를 고르는 방법의 수 만큼 로또를 구매하며, 같은 방법으로 2장이상 구매하지 않는다.
n과 m이 주어졌을 때, 선영이가 구매하는 로또의 개수를 출력하는 프로그램을 작성하시오.
입력
첫째 줄에 테스트 케이스의 개수 T가 주어진다. 각 테스트 케이스는 n과 m으로 이루어져 있다.
출력
각 테스트 케이스에 대해 선영이가 로또를 몇 개나 구매하는지 한 줄에 하나씩 출력한다.
2. 풀이
//dp[i][j]: 마지막으로 선택한 수가 j인 i개의 로또 번호
vector<vector<long long>> dp(n + 1, vector<long long>(m + 1, 0));
위와 같이 메모이제이션 배열을 설정한다고 하자.
for (int i = 1; i <= m; i++) {
dp[1][i] = 1;
}
마지막 숫자가 i인 1개의 로또 번호는 i를 번호로 선택하는 경우 한 가지 뿐이므로 위와 같이 초기화할 수 있다.
for (int k = 2; k <= n; k++) {
for (int i = 1; i * 2 <= m; i++) {
for (int j = i * 2; j <= m; j++) {
dp[k][j] += dp[k - 1][i];
}
}
}
이전에 고른 수보다 적어도 두 배가 되는 수를 선택하는 조건이 붙어있다. i를 이전의 마지막 수, j를 이후에 붙일 수라 정하면 j는 i의 두 배부터 시작하고, 문제의 조건에 따라 m 이하여야 한다. 이러면 k개의 수의 로또 번호를 정하는 경우는 k-1개의 i로 끝나는 로또 번호에 j를 붙이는 경우이다. 따라서 위와 같은 점화식을 세울 수 있다.
for (int i = 1; i <= m; i++) {
ans += dp[n][i];
}
cout << ans << '\n';
n개의 수를 뽑는 것이 문제이므로, n개의 수를 뽑는, 모든 경우를 더하여 출력하면 정답을 구할 수 있다.
'Coding Test' 카테고리의 다른 글
| 백준 21923 곡예 비행 (C++) (0) | 2024.09.23 |
|---|---|
| 백준 2073 수도배관공 (C++) (1) | 2024.09.22 |
| 백준 2631 줄세우기 (C++) (0) | 2024.09.09 |
| 백준 18427 함께 블록 쌓기 (C++) (0) | 2024.09.06 |
| 백준 12904 A와 B (C++) (0) | 2024.09.03 |