https://www.acmicpc.net/problem/16917
2초 / 512MB
문제
현진 치킨에서 판매하는 치킨은 양념 치킨, 후라이드 치킨, 반반 치킨으로 총 세 종류이다. 반반 치킨은 절반은 양념 치킨, 절반은 후라이드 치킨으로 이루어져있다. 양념 치킨 한 마리의 가격은 A원, 후라이드 치킨 한 마리의 가격은 B원, 반반 치킨 한 마리의 가격은 C원이다.
상도는 오늘 파티를 위해 양념 치킨 최소 X마리, 후라이드 치킨 최소 Y마리를 구매하려고 한다. 반반 치킨을 두 마리 구입해 양념 치킨 하나와 후라이드 치킨 하나를 만드는 방법도 가능하다. 상도가 치킨을 구매하는 금액의 최솟값을 구해보자.
입력
첫째 줄에 다섯 정수 A, B, C, X, Y가 주어진다.
출력
양념 치킨 최소 X마리, 후라이드 치킨 최소 Y마리를 구매하는 비용의 최솟값을 출력한다.
제한
- 1 ≤ A, B, C ≤ 5,000
- 1 ≤ X, Y ≤ 100,000
- 반반 치킨을 두 마리 구입해 양념 치킨 하나와 후라이드 치킨 하나를 만드는 방법도 가능
- 양념 치킨 한 마리의 가격은 A원, 후라이드 치킨 한 마리의 가격은 B원, 반반 치킨 한 마리의 가격은 C원
- 다섯 정수 A, B, C, X, Y
- 1 ≤ A, B, C ≤ 5,000
- 1 ≤ X, Y ≤ 100,000
- 양념 치킨 최소 X마리, 후라이드 치킨 최소 Y마리를 구매하는 비용의 최솟값
풀이 (C++)
- iostream
- algorithm
- 브루트 포스
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
long long a, b, c, x, y;
cin >> a >> b >> c >> x >> y;
long long ans = -1;
c *= 2LL;
for (int ban = 0; ban <= max(x, y); ban++) {
int yang = x - ban;
int hu = y - ban;
if (yang < 0) yang = 0;
if (hu < 0) hu = 0;
long long tmp = yang*a + hu*b + ban*c;
if (ans == -1 || ans > tmp) ans = tmp;
}
cout << ans;
}
|
cs |
풀이 과정
문제의 핵심은 반반치킨
반반치킨은 두 개 단위로 구매할 수 있고, 반반치킨 두 개 = 양념치킨 하나 + 후라이드치킨 하나
치킨을 딱 맞게 구매할 필요 없이 최소 X마리, Y마리 구매하면 되므로 가격만 싸다면 개수가 넘어도 된다
반반치킨의 개수를 0개부터 시작하여 X, Y 중 더 큰 값까지 살펴본다
최악의 경우가 100000 ( 0이 5개 )이므로 충분히 2초 내에 가능 ( 브루트 포스의 근거 )
다음은 x=3이고 y=2일 때 오로지 개수만 따진 표이다
다음과 같은 4가지 경우의 수가 나오며, 모든 경우의 수에 대해 최소 가격을 찾아주면 된다
제일 오른쪽 줄은 반반치킨으로 만든 양념/후라이드의 갯수를 칭한다
초록색 네모와 같이 음수가 나올 수 있다 ( 사야 할 개수가 음수라는 뜻이므로 1개가 남는다는 뜻 )
그러나 위에서 살펴봤듯 치킨은 남을 수 있으니 가격을 계산할 때는 음수는 0으로 취급한다
남을 수 있다고 해서 x, y보다 더 사는 경우는 무조건 최솟값보다 더 사게 되므로 x, y 중 큰 수까지만 고려해준다
( 목표는 몇 개를 사던지 간에 최소 x, y 개를 사기만 하면 되는데, 그 중 최소 가격을 찾는 것이기 때문 )
- 7번 줄 // 수 입력 순서 주의
- 9번 줄 // 어짜피 반반치킨은 두 개 단위로 구매해야 하므로 값을 두배시켜 준다
- 10~17번 줄 // ban은 반반치킨의 갯수( 의 1/2개 ) , x, y중 더 큰 값까지 살펴본다
- 11~12번 줄 // 양념 후라이드 단일 구매 갯수에서 반반치킨에 의해 감소되는 양 계산
- 13~14번 줄 // 만약 음수라면 ( 그만큼의 치킨이 남는다면 ) 0으로 처리
- 15번 줄 // 가격 계산
- 16번 줄 // 정답 비교, 초기화를 -1로 해두어서 대소비교가 적절히 이루어지도록 한다 ( 0으로 해두면 0이 계속 최솟값일 것이므로, 그런데 a,b,c 모두 최솟값이 1이라 가격이 0인 경우는 없긴 하다 )
- 18번 줄 // 정답 출력
주의사항
- 정답이 int 범위를 넘을 수 있다 ( 곱하기 형변환 주의 / int 끼리 곱한다고 long long 안된다==> 이 코드에서는 변수부터 long long으로 선언해서 해결 )
- 주어진 치킨의 개수는 '최소'임 ( 치킨이 남을 수 있음 )
- 정답 비교할 때 가능한 경우의 최솟값보다 작은 수 또는 최대값 보다 큰 수로 초기화 해둬야 한다
'BOJ' 카테고리의 다른 글
C++) BOJ 풀이// 16968: 차량 번호판 1 (0) | 2020.03.07 |
---|---|
C++) BOJ 풀이// 1725: 히스토그램, 6549: 히스토그램에서 가장 큰 직사각형 (Largest Rectangle in a Histogram) (0) | 2020.03.06 |
C++) BOJ 풀이// 12865: 평범한 배낭 (1) | 2020.03.05 |
C++) BOJ 풀이// 3053: 택시 기하학 (HERMAN) (0) | 2020.03.05 |
C++) BOJ 풀이// 1002: 터렛 (0) | 2020.03.04 |