题目链接:Swaps and Inversions
题意:给定一串数组,发现其中的含有一个逆序对则需要花费x元,交换相邻两个数需要花费y元,输出最小花费。
题解:
逆序对个数=交换相邻两个数的总次数
仔细思考可以发现,最小花费是 逆序对个数*min(x,y) 所以这题其实就是求出数组中的逆序对个数即可。我用的是归并排序求逆序对个数。
AC代码:
//HDU 6318
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int MAXN=1e5+10;
ll tmp[MAXN],a[MAXN],n,x,y,ans;
inline void Merge_sort(int l,int r)//归并求逆序对个数
{
if(l==r)
return ;
int m=(l+r)>>1;
Merge_sort(l,m);
Merge_sort(m+1,r);
int i=l,j=m+1,k=l;
while(i<=m&&j<=r)
{
if(a[i]>a[j])
{
tmp[k++]=a[j++];
ans+=(m-i+1);
}
else
tmp[k++]=a[i++];
}
while(i<=m)
tmp[k++]=a[i++];
while(j<=r)
tmp[k++]=a[j++];
for(int i=l;i<=r;i++)
a[i]=tmp[i];
}
int main()
{
while(~scanf("%lld%lld%lld",&n,&x,&y))
{
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);//注意输入格式,为long long 类型
ans=0;
Merge_sort(1,n);
printf("%lld\n",min(x,y)*ans);
}
return 0;
}