728x90
🔗 문제 링크
https://www.acmicpc.net/problem/1106
💡 문제 풀이 및 해석
- 냅색 문제지만, 주의해야 할 점이 한가지 있다.
적어도 C명 늘이기 위해 형택이가 투자해야 하는 돈의 최솟값
을 구해야 하는 것이다. 이는 C명을 늘리거나 혹은 그 이상 늘렸을 때, 최소비용이 되어야 한다는 뜻이다. 따라서 C명보다 많이 뽑아도 C명을 뽑을 때의 최소비용보다 낮다면 더 뽑아도 된다는 뜻이다. - 냅색 문제는 직접 보면 이해가 생각보다 쉬운 편이다. X에는 항상 최소비용이 들어가야 한다. 일단, 아무도 뽑지 않으면 0의 비용이 들어간다. 1명을 뽑을 때는 0명에서 1명을 뽑을 때 비용을 더해주면 된다. 2명을 뽑을때는
1명에서 1명을 더 뽑는 비용 vs 0명에서 2명
을 뽑는 비용 중에서 낮은 비용을 넣어준다. 3명을 뽑을 때는0명에서 3명 vs 1명에서 2명 vs 2명에서 1명
을 뽑는 비용 중에서 낮은 비용을 넣어준다. 0 1 2 3 4 5 6 7 8 9 10 11 // n명을 뽑을 때 0 X X X X X X X X X X X // 드는 비용
- 위와 같이 모든 경우를 구하지만, 최대 한번에 100명을 뽑을 수 있으니 1099명까지 뽑았을 때, 최소 비용을 구해야 한다. 그런데, 코드에서는 그냥 귀찮아서 1100으로 해놨다.
- 마지막으로 정렬하는 코드는 만약에 뽑는 인원이 처음부터 오버되면 그보다 많이 뽑는 경우는 체크하지 않기 위해서 최적화할려고 해둔 것인데, 문제풀이에는 그냥 넣지 않았다.
⭐️ 정답 코드 및 주석
#include<iostream>
#include<algorithm>
#include<vector>
#define INF 987654321
using namespace std;
int C, N; // 늘려야 하는 수, 도시의 갯수
int cost[1101];
vector<pair<int, int>> vec;
void input() {
cin >> C >> N;
for (int i = 1; i <= 1100; i++) {
cost[i] = INF;
}
for (int i = 0; i < N; i++) {
int cost, customer; cin >> cost >> customer;
vec.push_back({ customer,cost });
}
sort(vec.begin(), vec.end());
}
void sol() {
for (int i = 1; i <= 1100; i++) {
for (auto v : vec) {
int customer = v.first;
int cost_ = v.second;
if (i - customer > -1 && cost[i-customer] + cost_ < cost[i]) {
cost[i] = cost[i - customer] + cost_;
}
}
}
}
int main() {
input();
sol();
int answer = INF;
for (int i = C; i <= 1100; i++) {
answer = min(cost[i], answer);
}
cout << answer;
return 0;
}
🤔 문제 후기
음,,, 문제가 어렵진 않았는데, 조건중에서 C명이상이라는 말을 못봐서 계속 1000까지 구하는 것으로 해놨다가 낭패를 봤다. 문제를 좀더 꼼꼼히 읽어야겠다. 냅색 문제를 풀어보고 이해해본 사람이라면 어렵지 않은 문제라고 생각한다.
728x90
'알고리즘 문제 풀이' 카테고리의 다른 글
[ 백준 1197 ] 최소 스패닝 트리 (C++) - 최소 스패닝 트리 (0) | 2024.09.06 |
---|---|
[ 백준 1253 ] 좋다 (C++) - 투 포인터 (0) | 2024.09.05 |
[ 백준 1327 ] 소트 게임 (C++) - BFS (3) | 2024.09.04 |
[ 백준 1188 ] 음식 평론가 (C++) - 최대공약수 (1) | 2024.09.03 |
[ 백준 1034 ] 램프 (C++) - 패턴 (1) | 2024.09.02 |