728x90
개요
문제 링크
골드 5, Greedy, DP
팰린드롬을 만들기 위한 최소 swap 수
접근
- 처음에 upper bound를 이용해서 왼쪽부터 오름차순, 오른쪽부터 내림차순으로 정렬하면서 left_swap + right_swap의 최솟값을 구했는데 실패.
- 머리가 나빠서 다른 풀이는 생각 안남. 그냥 codejam 검색해서 analysis를 보고 이해했음. Greedy랑 DP가 섞이면 골5도 못푸는 멍청이라 너무 슬프다..
- DP보다는 그리디가 더 중요했던 문제, 방법은 최솟값을 선택하고, 왼쪽과 오른쪽 중 더 가까운 swap 수를 더하고, 최솟값을 지워주면 되는 데 이게 왜 되냐? 아래 예시를 보자.
875691243 -> 87569243(1) -> 8756943(21) -> 8756943(21) -> 875694(321)
-> 87569(4321) -> (5)8769(4321) -> (5)879(64321) -> (57)89(64321)
-> (5789)(64321)
알아서 최소의 swap을 통해 팰린드롬 정렬이 됐다. 왼쪽과 오른쪽 덩어리는 알아서 오름차순/내림차순으로 정렬되고 이게 최적임.
다시보니까 코드포스 Forbidden permutation과도 닮아 있다.
Pseudo code
while (n--)
i = get_min_index()
swap += min(i, n-i)
remove(i)
Source code
#include <bits/stdc++.h>
using namespace std;
vector <int> a;
int get() {
int m = 2e9, ans;
for (int i=0; i<a.size(); i++) {
if (a[i] < m)
ans = i, m = a[i];
}
return ans;
}
int test() {
int n;
cin >> n;
a.clear();
int x;
for (int i=0; i<n; i++)
cin >> x, a.push_back(x);
int ans = 0;
while (n--) {
int i = get();
ans += min(i, n-i);
a.erase(next(a.begin(),i));
}
return ans;
}
int main() {
int t;
cin >> t;
for (int i=1; i<=t; i++)
printf("Case #%d: %d\n",i,test());
}
728x90
'백준브실골 > Greedy' 카테고리의 다른 글
백준 7775, 최종 순위 (0) | 2023.02.19 |
---|---|
백준 2812, 크게 만들기 (0) | 2023.02.11 |
백준 1132, 합 (0) | 2023.02.11 |
백준 1339, 단어 수학 (0) | 2023.02.11 |
백준 13884, 삭삽 정렬 (0) | 2023.02.08 |
백준 4889, 안정적인 문자열 (0) | 2023.02.08 |
백준 9009, 피보나치 (0) | 2023.02.08 |
백준 25683, 행렬 곱셈 순서 4 (0) | 2023.02.08 |
댓글