https://www.acmicpc.net/problem/1727
1727번: 커플 만들기
첫째 줄에 n, m(1 ≤ n, m ≤ 1,000)이 주어진다. 다음 줄에는 n명의 남자들의 성격이 주어진다. 그 다음 줄에는 m명의 여자들의 성격이 주어진다. 성격은 1,000,000이하의 자연수이다.
www.acmicpc.net
솔루션
해당 문제를 접하기 전에 먼저 풀었던 문제가 있는데, (https://www.acmicpc.net/problem/8902)
그 문제와 유사해서 접근은 금방 할 수 있었다.
먼저 남/여 중 더 적은 것은 v0배열에 담고, 다른 것은 v1 배열에 담는다
그리고 각각 정렬을 해 준다.
이를 통해 i <-> j +1 과 i+1 <-> j일 경우는 없어지며, (꼬인 형태로 매칭되지 않으며) 남은 부분의 해가 최적해가 될 수 있도록 할 수 있다. 즉 dp이다.
남/여 쌍을 무조건 최대로 맞춰야하기 때문에,
v0의 원소는 무조건 다 매칭 되어야 한다.
그리고 v0의 i명과, v1의 j명이 매칭이 됐을 때, 남은 N- i명, M-j 명이 매칭이 되었을 때의 최소값을 저장을 한다.
나는 재귀식으로 dp를 짰는데
1. i에서 j의 원소와 매칭을 하는 경우 -> 성격 차이를 계산 + 재귀 i+1, j+1을 호출
2. i에서 j의 원소와 매칭하지 않는 경우 -> 0 + 재귀 i, j+1을 호출
따라서 점화식은 dp[i][j] = min ( func(i+1,j+1) + 성격차이, func(i, j+1) ) 로 세울 수 있다.
그리고 기저상황은
1. i의 원소가 무조건 매칭되어야 하므로 v0에 남은 사람이 더 많은 경우 -> 무한대 리턴
2. i가 다 매칭 된 경우 -> 0 리턴
3. 이미 방문한 dp 배열이라면 -> dp배열 리턴
코드
#define INF 210000000000;
#define ll long long int
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int N, M;
ll dp[1002][1002];
vector<int> v0;
vector<int> v1;
ll solve(int i, int j) {
//남은 i의 수가 더 많으면 안됨.
if (v0.size() - i > v1.size() - j) return dp[i][j] = INF;
//짝을 다 맞췄으면 리턴.
if (i == v0.size()) return 0;
//이미 방문했더라면, 리턴
if (dp[i][j] != 0) return dp[i][j];
ll& ref = dp[i][j] = INF;
//짝을 맞춰주는 경우
ref = min(solve(i + 1, j + 1) + abs(v0[i] - v1[j]), ref);
//다음 짝을 맞추는 경우
ref = min(solve(i, j + 1), ref);
return ref;
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
cin >> N >> M;
int value;
if (N > M) {
for (int i = 0; i < N; i++) {
cin >> value;
v1.push_back(value);
}
for (int j = 0; j < M; j++) {
cin >> value;
v0.push_back(value);
}
}
else {
for (int i = 0; i < N; i++) {
cin >> value;
v0.push_back(value);
}
for (int j = 0; j < M; j++) {
cin >> value;
v1.push_back(value);
}
}
sort(v0.begin(), v0.end());
sort(v1.begin(), v1.end());
cout << solve(0, 0) << '\n';
}
'백준' 카테고리의 다른 글
C++[백준]26972번 Barn Tree (4) | 2023.11.03 |
---|---|
C++[백준]11025번 요세푸스 문제 3 (0) | 2023.10.30 |
C++[백준]1493번 박스 채우기 (1) | 2023.10.25 |
C++[백준]20529 가장 가까운 세 사람의 심리적 거리 (0) | 2023.07.11 |
C++[백준]20303번 할로윈의 양아치 (0) | 2023.07.04 |