题目链接:2018 Multi-University Training Contest 2
6318 Swaps and Inversions
题意:sum=x*逆序个数+交换次数*y,使sum最小
思路:反复观察发现,如果有逆序对,那么就一定有相邻的逆序对,而且交换他们一定是合理的
进一步发现,逆序对的数量即是最大交换的次数,最后,ans=min(x,y)*逆序个数
使用分治排序求逆序对个数:
#include<cstdio> #include<iostream> #include<set> using namespace std; const int maxn=1e5+10; long long ans; int num[maxn],num2[maxn]; void ins(int bg,int md,int ed) { int a=bg,b=md+1; int now=bg; while(a<=md&&b<=ed) { if(num[a]<=num[b])num2[now]=num[a],a++; else num2[now]=num[b],b++,ans+=(md-a+1); now++; } while(a<=md)num2[now++]=num[a++]; while(b<=ed)num2[now++]=num[b++]; for(int i=bg;i<=ed;i++)num[i]=num2[i]; } void mysort(int bg,int ed) { if(bg==ed)return; int md=(bg+ed)/2; mysort(bg,md); mysort(md+1,ed); ins(bg,md,ed); } int main() { int n,a,b; while(cin>>n>>a>>b) { ans=0; for(int i=1;i<=n;i++) scanf("%d",&num[i]); mysort(1,n); cout<<ans*min(a,b)<<endl; } return 0; }