※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※

 

이번에 볼 문제는 백준 14943번 문제인 벼룩 시장이다.
문제는 아래 링크를 확인하자.

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

 

각자가 사거나 팔고자 하는 벼룩의 양의 모두 1인 경우를 먼저 생각해보자. 이 경우, 벼룩을 사고자 하는 사람들의 위치와 팔고자 하는 사람들의 위치를 각각 크기순으로 나열하고, 두 위치를 크기순으로 서로 매칭시키는 경우에 비용이 최소가 된다. 증명은 exchange argument로 어렵지 않게 할 수 있다. 또한 같은 논리로 같은 위치에 벼룩을 사거나 팔고자 하는 사람이 여럿 있어도 같은 방식으로 최소 비용을 구할 수 있음을 알 수 있다.

 

한 사람이 A마리의 벼룩을 사거나 팔고자 하는 것을 A명의 사람이 같은 위치에서 각각 한 마리의 벼룩을 사거나 팔고자 하는 것으로 생각해 위의 논리대로 문제를 해결하자. 다만 실제로 마릿수대로 사람을 한명씩 모두 나누어 구현하는 것은 (특히 메모리면에서) 비효율적이므로, 각 사람의 위치 단위로 문제를 해결하자. 이는 투 포인터 기법으로 어렵지 않게 구현 가능하다.

 

아래는 제출한 소스코드이다.

#include <iostream>
#include <vector>
using namespace std;
typedef long long ll;

int N;
vector<pair<int, int>> L, R;
int lsize, rsize, idxL, idxR;
ll ans;

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);

	cin >> N;
	for (int i = 1; i <= N; i++) {
		int x; cin >> x;
		if (x < 0) L.emplace_back(make_pair(-x, i));
		else R.emplace_back(make_pair(x, i));
	}
	lsize = L.size(), rsize = R.size();
	while (idxL < lsize && idxR < rsize) {
		ll val = min(L[idxL].first, R[idxR].first);
		ans += val * abs(L[idxL].second - R[idxR].second);
		L[idxL].first -= val;
		if (!L[idxL].first) idxL++;
		R[idxR].first -= val;
		if (!R[idxR].first) idxR++;
	}
	cout << ans;
}
728x90

+ Recent posts