본문 바로가기

백준

C++[백준]1781번 컵라면

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

 

1781번: 컵라면

상욱 조교는 동호에게 N개의 문제를 주고서, 각각의 문제를 풀었을 때 컵라면을 몇 개 줄 것인지 제시 하였다. 하지만 동호의 찌를듯한 자신감에 소심한 상욱 조교는 각각의 문제에 대해 데드라

www.acmicpc.net

 

솔루션


처음에 데드라인이 가장 늦게 끝나는 것 부터 채워 오다가 시간초과를 받았다.

 

그래서 떠 올린 방법이 우선순위 큐 2개를 이용해서 푸는 방법이다

 

아직 처리 안한 문제를 담은 pq1

 - 데드라인이 빠른 것 부터, 같다면 컵라면 수를 많이 주는 것부터

 

내가 처리한 문제들을 담은 pq2

 - 컵라면의 개수가 가장 낮은 것부터 (이때 deadline은 상관 없을 것 같다.)

 

 

for문을 i를 통해서 1일부터 N일 까지 돌게 되는데,

 pq1에서 i일이 데드라인일 때, 컵라면 개수를 많이 주는 것을 pq2로 담아주고 pq1에서 뽑아준다.

 이를 pq2의 사이즈가 i가 될 때 까지 반복한다.(pq2의 개수는 1일에 1문제를 할 수 있으므로 사이즈만큼 더 할 수 있다)

 

 그리고 pq1에서 아직 현재 날짜의 데드라인인 문제가 남아있다면

   pq2의 컵라면수가 가장 낮은 것보다 pq1의 컵라면 수가 더 많이 준다면

   pq2의 컵라면수를 빼 주고, pq1의 컵라면 수를 더해준다.

 

 그리고 해당 데드라인까지 처리 못한 작업이 pq1에 남아있는데 이를 다 뽑아준다.

 

 

 

코드


#include <iostream>
#include <queue>
using namespace std;

struct pa {
	int deadline, cnt;
	//데드라인이 낮은 것 부터 pq.top에 오도록
	bool operator<(const struct pa& t) const {
		//같으면 cnt가 큰 것이 오도록
		if (deadline == t.deadline) {
			return cnt < t.cnt;
		}
		return deadline > t.deadline;
	}
};

//이미 처리한 일
struct work {
	int deadline, cnt;
	//cnt가 가장 낮은 것이 top에 오도록
	bool operator<(const struct work& t) const {
		if (cnt == t.cnt) {
			//deadline은 상관 없음
			return deadline < t.deadline;
		}
		return cnt > t.cnt;
	}
};

int N;
priority_queue<struct pa> pq;
priority_queue<struct work> pq2;
int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL); cout.tie(NULL);

	cin >> N;

	for (int i = 0; i < N; i++) {
		int dead, cnt;
		cin >> dead >> cnt;
		pq.push({ dead,cnt });
	}

	int ans = 0;
	for (int i = 1; i <= N; i++) {
		//데드라인날인데, 그 앞에 처리한 일이 현재 날짜보다 개수가 작을 때,
		while (!pq.empty() && pq2.size() < i && pq.top().deadline <= i) {
			ans += pq.top().cnt;
			pq2.push({ pq.top().deadline,pq.top().cnt });
			pq.pop();
		}

		//데드라인이 더 늦는데, 더 많은 양을 얻을 수 있을 때.
		while (!pq.empty() && !pq2.empty() && pq2.top().cnt < pq.top().cnt && pq.top().deadline <= i) {
			ans -= pq2.top().cnt;
			pq2.pop();
			ans += pq.top().cnt;
			pq2.push({ pq.top().deadline,pq.top().cnt });
			pq.pop();
		}

		while (!pq.empty() && pq.top().deadline == i) pq.pop();
	}
	cout << ans << "\n";
}

'백준' 카테고리의 다른 글

C++[백준]16968 차량 번호판 1  (0) 2023.03.07
C++[백준]20040번 사이클 게임  (0) 2023.02.14
C++[백준]16496번 큰 수 만들기  (0) 2023.02.13
C++[백준]2473번 세 용액  (0) 2023.02.13
C++[백준]2143번 두 배열의 합  (0) 2023.02.12