2018 Multi-University Training Contest 2-1010-Swaps and Inversions
题目链接http://acm.hdu.edu.cn/contests/contest_showproblem.php?pid=1010&cid=803
题目大意
一个乱序的序列,每个逆序对需花费x,可以花费y交换相邻数字,求最小花费
简单思路
找出逆序对数目m,然后比较x、y的大小,m*min(x,y)
ac代码
#include<bits/stdc++.h> using namespace std; #define inf 0x3FFFFFFF #define fo(i,a,b) for(int i=a;i<=b;i++) #define fo_(i,a,b) for(int i=a;i>=b;i--) #define ll long long #define M(a) memset(a,0,sizeof a) #define M_(a) memset(a,-1,sizeof a) #define pb push_back const ll mod=1000000007; ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;} ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;} #define maxn 100010 #define MAX_VALUE 12343564 int x,y,n; int a[maxn]; ll cnt; void merge(int *a , int first, int mid, int last) { int * temp = new int[last - first + 1]; int first1 = first, last1 = mid; int first2 = mid + 1, last2 = last; int index = 0; while(first1 <= last1 && first2 <= last2) { if(a[first1 ] <= a[first2]) { temp[index++] = a[first1++]; } else { cnt += last1 - first1 + 1; temp[index++] = a[first2++]; } } while(first1 <= last1) { temp[index++] = a[first1++]; } while(first2 <= last2) { temp[index++] = a[first2++]; } int i; for(i = first; i <= last; i++) { a[i] = temp[i - first]; } delete [] temp; return; } void inv_pair(int *a, int first, int last) { if(last - first > 0) { int mid = (last + first) / 2; inv_pair(a, first, mid); inv_pair(a, mid + 1, last); merge(a, first, mid, last); } return; } int main() { while(~(scanf("%d %d %d",&n,&x,&y))){ cnt=0; fo(i,0,n-1){ scanf("%d",&a[i]); } inv_pair(a,0,n-1); ll min_s; min_s=min(cnt*x,cnt*y); printf("%lld\n",min_s); } return 0; }
总结
解题关键在于找出逆序对

浙公网安备 33010602011771号