https://www.acmicpc.net/problem/1495
1495번: 기타리스트
첫째 줄에 N, S, M이 주어진다. (1 ≤ N ≤ 50, 1 ≤ M ≤ 1,000, 0 ≤ S ≤ M) 둘째 줄에는 각 곡이 시작하기 전에 줄 수 있는 볼륨의 차이가 주어진다. 이 값은 1보다 크거나 같고, M보다 작거나 같다.
www.acmicpc.net
전형적인 다이나믹 프로그래밍 문제. 시작 볼륨부터 시작해서 각 곡이 끝날 때마다 가능한 볼륨을 모두 탐색해 저장하면 풀 수 있다.
#include <cstdio>
#define MAX_N 50
#define MAX_M 1000
int main() {
// vol[i][j]: i번째 곡을 연주한 직후 볼륨이 j인 경우가 있다면 true
bool vol[MAX_N + 1][MAX_M + 1] = {{ false, }};
// N: 연주할 곡의 수, S: 초기 볼륨, M: 최대 볼륨
int N, S, M;
// c_vol[i]: i번째 곡을 연주한 직후 바꿀 수 있는 볼륨의 크기
short c_vol[MAX_N + 1] = { 0, };
// 문제의 조건을 입력받는다
scanf("%d %d %d", &N, &S, &M);
for (int i = 0; i < N; i++) scanf("%hd", &c_vol[i]);
// 0번째 곡을 연주한 직후, 즉 공연 직전 볼륨을 S로 정한다
vol[0][S] = true;
// i번째 곡을 연주한 직후 볼륨이 j일 가능성이 있다면
for (int i = 0; i < N; i++) for (int j = 0; j <= M; j++) if (vol[i][j]) {
// j +- c_vol[i]이 범위 내 볼륨이라면 해당 볼륨으로 연주할 수 있다
if (j + c_vol[i] <= M) vol[i + 1][j + c_vol[i]] = true;
if (j - c_vol[i] >= 0) vol[i + 1][j - c_vol[i]] = true;
}
// N번째 곡을 연주한 직후 가능한 최대 볼륨을 찾아 출력
for (S = M; S >= 0 && !vol[N][S]; S--);
printf("%d\n", S);
return 0;
}
'알고리즘 > 문제 풀이' 카테고리의 다른 글
1541번: 잃어버린 괄호 (0) | 2021.12.08 |
---|---|
1504번: 특정한 최단 경로 (0) | 2021.12.08 |
1476번: 날짜 계산 (0) | 2021.12.08 |
1475번: 방 번호 (0) | 2021.12.08 |
1463번: 1로 만들기 (0) | 2021.12.08 |