본문 바로가기
풀이

[백준] 2322 - 아령, 2569 - 짐정리 (c++)

by 땅왕 2024. 9. 26.

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

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

 

문제 요약

N개의 물건이 있고 각각 무게가 주어진다. 두 물건의 위치를 바꿀수 있고 두 무게의 합만큼의 힘이 들 때 최소 힘으로 물건을 무게순으로 정렬해라.

 

풀이 (NlogN)

  • 순열 사이클 분할
  • 그리디

오름차순으로 정렬 했을 때 자리가 바뀌는 수는 모두 사이클에 속하게 된다. 사이클엔 오름차순을 했을 때에 각 순서의 숫자가 모두 포함되어 있기 때문에 각각에 사이클에서 오름차순을 해준다면 전체도 오름차순이 된다. 사이클 안에서 정렬하는 비용은 사이클 안에 가장 작은 원소를 이용하는 방법(cymin*(cnt-2)+sum) 전체에서 가장 작은 원소를 사이클 내 가장 작은 원소와 바꿨다가 돌려놓는 방법(min*(cnt+1)+sum+cymin) 중 작은 것이 최소이다.

#include <bits/stdc++.h>
using namespace std;
#define ll long long

int main() {
    cin.tie(0)->sync_with_stdio(0);
    int n;cin>>n;
    array<ll,2> g[n];
    int i=0;
    for(auto& [a,b]:g) cin>>a,b=i++;
    sort(g,g+n);
    bool vis[n]{};ll ans=0;
    for(int i=0;i<n;i++) {
        if(vis[i]) continue;
        int cnt=0;
        for(int j=i;!vis[j];j=g[j][1])
            vis[j]=1,cnt++,ans+=g[j][0];
        ans+=min(g[0][0]*(cnt+1)+g[i][0],g[i][0]*(cnt-2));
    }
    cout<< ans;
}

 

감상

순열 사이클 분할로 이런 문제를 해결할 수 있다는게 정말 신기했다. 

'풀이' 카테고리의 다른 글

[백준] 11689 - GCD(n, k) = 1 (c++)  (0) 2024.10.08
[백준] 21099 - Four XOR (c++)  (1) 2024.09.28
[백준] 20870 - Teleportgång (c++)  (0) 2024.09.24
[백준] 28493 - Burgers (c++)  (0) 2024.09.21
[백준] 26268 - 은?행 털!자 2 (c++)  (1) 2024.09.01