책 나눠주기
코드
[ 이분매칭 풀이 ]
#include <cstdio>
#include <vector>
#include <queue>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <set>
#define ll long long
using namespace std;
vector<pair<int,int>> v(1010);
int work[1010];
bool finish[1010];
int T, N, M;
bool DFS(int x){
for(int t=v[x].first;t<=v[x].second;t++)
{
if(finish[t]) continue;
finish[t] = true;
if(work[t] == -1 || DFS(work[t])){
work[t] = x;
return true;
}
}
return false;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> T;
while(T--)
{
v.clear();
cin >> N >> M;
for(int i=0;i<M;i++)
{
int a, b;
cin >> a >> b;
v.push_back({a,b});
}
fill(work, work+1010, -1);
int ans=0;
for(int i=0;i<M;i++)
{
fill(finish, finish+1010, false);
if(DFS(i)) ans++;
}
cout << ans << '\n';
}
return 0;
}
- 로직
모든 사람
에 대해서 이분매칭 DFS
수행
: 내가 선택한 책
이 이미 선택
되어 있다면
그 책을 선택한 사람
에게 다른 책
을 선택
하도록 권유!
[ 그리디 풀이 ]
#include <cstdio>
#include <vector>
#include <queue>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <set>
#define ll long long
using namespace std;
bool compare(pair<int,int> n, pair<int,int> c)
{
if(n.second == c.second)
return n.first < c.first;
return n.second < c.second;
}
int T, N, M;
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> T;
while(T--)
{
cin >> N >> M;
vector<pair<int,int>> v;
bool vis[N+1];
fill(vis, vis+N+1, false);
for(int i=0;i<M;i++)
{
int a, b;
cin >> a >> b;
v.push_back({a,b});
}
sort(v.begin(), v.end(), compare);
int ans=0;
for(int i=0;i<v.size();i++)
{
for(int j=v[i].first; j<= v[i].second;j++)
{
if(vis[j]) continue;
vis[j] = true;
ans++;
break;
}
}
cout << ans << '\n';
}
return 0;
}
- 로직
책의 범위
를 (st, en)
라고 했을 때
en이 작은 순서
대로 정렬, en이 같다면
st이 작은 순서
대로 정렬
정렬된 순서의 사람
순서대로 책 할당!
- 이해
- 이 문제를
greedy
하게 접근
하기 위한 명확한 증거
를 찾지 못함
이분매칭
의 경우에 그리디
로 풀어낼 수 있다는 것
정도 인지하자