fragment-header
fragment-markdown
홈
로그인
로그아웃
내 블로그
설정
로그인
백준 17305 (C++) 사탕 배달
최초 업로드: 2025-07-18 09:37:15
최근 수정 시간: 2025-07-25 08:44:13
게시자: rlatjwls3333
카테고리: 백준
조회수: 3
# [Gold IV] 사탕 배달 [문제 링크](https://www.acmicpc.net/problem/17305) ## 문제 설명 <p>사탕을 좋아하는 아기 석환은, 집에 <em>N</em>개의 사탕이 들어있는 자루를 들여놓았다. 자루에는 두 가지 종류의 사탕이 있는데, 작은 사탕은 3g의 무게를 가지고, 큰 사탕은 5g의 무게를 가진다. 똑똑한 아기 석환은 자루에 있는 모든 사탕에 대해서, 그 사탕의 당도 <em>s<sub>i</sub></em> 를 계산해 놓았다. <em>s<sub>i </sub></em>는 양의 정수로, <em>s<sub>i</sub></em> 가 클수록 사탕은 달콤하다.</p> <p>shake! 2019 대회에 참가하기 위해 짐을 싸고 있는 아기 석환은, 달콤한 사탕을 최대한 많이 담아가서 대회 도중 당분을 보충하려고 한다. 하지만, 연약한 아기 석환은 가방에 최대 <em>w</em>g (<em>w</em>그램) 의 사탕만을 담을 수 있다. 아기 석환이 이 조건을 만족하면서 사탕을 담았을 때, 담아간 사탕의 당도의 합은 최대 얼마가 될 수 있을까?</p> ## 입력 <p>첫 번째 줄에 사탕의 개수 <em>N</em>(1 ≤ <em>N</em> ≤ 250,000), 무게 제한 <em>w</em>(0 ≤ <em>w</em> ≤ 5<em>N</em>)가 주어진다.</p> <p>이후 <em>N</em>개의 줄에 각 사탕의 종류 <em>t<sub>i</sub></em>, 당도 <em>s<sub>i</sub></em>가 주어진다. ($t_i \in \{3, 5\}$, 1 ≤ <em>s<sub>i</sub></em> ≤ 10<sup>9</sup>)</p> ## 출력 <p>아기 석환이 조건을 만족하면서 담아갈 수 있는 사탕의 당도의 최대 합을 출력하라.</p> ## 풀이 #### 전체 집합은 무게가 3인 사탕들과 무게가 5인 사탕들 두 덩어리가 되니, 무게별로 나눈 후 정렬해서, 가치가 높은 사탕들부터 그리디하게 추가해보며 모든 경우에 대해 최대값을 찾아주었다. ``` c++ #include<bits/stdc++.h> using namespace std; const int MAX = 1'000'000; long long preSum[MAX+1]; // 무게가 3인 사탕들의 누적합 int main() { ios::sync_with_stdio(0); cin.tie(0); int n, w; cin >> n >> w; vector<int> weight3, weight5; while(n--) { int t, s; cin >> t >> s; if(t==3) weight3.push_back(s); else weight5.push_back(s); } sort(weight3.begin(), weight3.end(), greater<int>()); sort(weight5.begin(), weight5.end(), greater<int>()); for(int i=0;i<weight3.size();i++) preSum[i+1] = preSum[i] + weight3[i]; for(int i=weight3.size()+1;i<=MAX;i++) preSum[i] = preSum[i-1]; long long maxS = preSum[w/3], total=0; for(int i=0;i<weight5.size() && (i+1)*5<=w;i++) { total += weight5[i]; maxS = max(maxS, total + preSum[max((w-(i+1)*5)/3, 0)]); // 일부분 무게 5인 사탕, 나머지부분 무게 3인 사탕 } cout << maxS; } ```