[BOJ 5896] 효율적으로 소 사기

2023. 1. 17. 20:47Baekjoon

728x90

 

https://www.acmicpc.net/problem/5896

 

5896번: 효율적으로 소 사기

첫 번째 줄에 소 시장에 나온 소들의 마릿수 N(1 ≤ N ≤ 50,000), 농부 존이 가지고 있는 쿠폰의 개수 K(1 ≤ K ≤ N), 농부 존이 가지고 있는 돈 M(1 ≤ M ≤ 1014)이 주어진다. 다음 줄부터 Pi (1 ≤ Pi ≤

www.acmicpc.net

 

- 문제 요약

 

농부 존은 새 소들이 필요하다! 그래서 농부 존은 소 시장에 가서 새 소들을 사려고 한다.

농부 존은 돈이 많이 없기 때문에 소들을 최대한 효율적으로 사야 한다. 그래서 농부 존은 M원과 K개의 소 쿠폰을 가지고 소 시장에 나온 N마리의 소들을 최대한 많이 사려고 한다.

소 쿠폰은 소 한 마리당 한 번만 쓸 수 있고, 쓰고 나면 사라진다. i번째 소는 Pi원이고, 쿠폰을 썼을 때는 Ci원이 될 때, 농부 존이 최대로 살 수 있는 소의 마릿수를 출력하라.

 

 

- 알고리즘 정리

 

첫 번째로 생각해 낸 아이디어는 비용이 적은 순(Pi 기준 오름차순)으로 정렬한 후 쿠폰을 사용하며 소를 구매하는 방법으로 코드를 짜려했는데, 이렇게 하면 Pi와 Ci의 격차가 큰 소를 놓치는 경우가 생기게 됩니다. ( = 반례가 생긴다 )

그렇기에 소를 정렬할 때, Ci 기준으로 정렬 후 쿠폰을 사용하는 경우와 사용하지 않는 경우를 나눠서 처리해줍니다. 쿠폰이 남아있을 때 쿠폰을 사용하는 경우와 사용하지 않는 경우를 비교해서 돈이 많이 남는 경우를 선택하면 됩니다.

 

 

- 코드 작성

 

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
ll n,k,m,a,b,result;
vector<pair<ll,ll> >v;
struct compare{
	bool operator()(pair<ll,ll>a,pair<ll,ll>b){
		return a.first>b.first;
	}
};
priority_queue<pair<ll,ll>,vector<pair<ll,ll> >,compare>pq;

bool cmp(pair<ll,ll>a, pair<ll,ll>b){
	if(a.second==b.second){
		return a.first<b.first;
	}
	else{
		return a.second<b.second;
	}
}

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	cin>>n>>k>>m;
	for(int i=0;i<n;i++){
		cin>>a>>b;
		v.push_back({a,b});
	}
	sort(v.begin(),v.end(),cmp);
	for(int i=0;i<n;i++){
		if(k>0){ // 쿠폰있음 
			if(m<v[i].second){
				break;
			} 
			m-=v[i].second;
			pq.push(v[i]);
			k--;
			result++;
		}
		else{ // 쿠폰없음 
			ll aa,bb;
			pair<ll,ll>t=pq.top();
			aa=m-v[i].first;
			bb=(m+t.second)-(t.first+v[i].second);
			if(aa<0 and bb<0){
				continue;
			}
			else{
				result++;
			}
			if(aa>=bb){
				m=aa;
			}
			else{
				m=bb;
				pq.pop();
				pq.push(v[i]);
			}
		} 
	}
	cout<<result;
}

코드 제출 결과

아이디어 떠올리는게 힘들었던 문제...

코드 구현은 간단한데 쿠폰을 사용하는 경우의 수를 나누고 그걸 우선순위 큐에 접목시킬 아이디어를 떠올려야 하니...

플3 정도의 문제는 맞는 것 같네요.

728x90

'Baekjoon' 카테고리의 다른 글

[BOJ 14452] Cow Dance Show  (0) 2023.01.23
[BOJ 14172] Moocast  (0) 2023.01.20
[BOJ 17412] 도시 왕복하기 1  (0) 2023.01.12
[BOJ 3830] 교수님은 기다리지 않는다  (0) 2022.08.20
[BOJ 1655] 가운데를 말해요  (0) 2022.05.04