H. Maximizer

https://codeforces.com/group/5yyKg9gx7m/contest/280318/problem/H
题意:给定n的排列,A和B,求A的最少相邻交换次数,使得A和B每个位置差的绝对值之和最大。
思路: i i i对应 n + 1 − i n+1-i n+1i是一种,另外,如果n是偶数,则 [ 1 , n / 2 ] [1,n/2] [1,n/2] [ n / 2 + 1 , n ] [n/2+1,n] [n/2+1,n]任意对应都行,若n为奇数, n / 2 + 1 n/2+1 n/2+1分到左右边都可以,取较小的。
移动次数的话,按坐标从左到右依次取差的绝对值之和即可。 O ( n ) O(n) O(n)

#include
using namespace std;
const int maxn=250000+100;
typedef pair<int,int> P;
typedef long long ll;
#define MP(a,b) make_pair(a,b)

int n,a[maxn],b[maxn];

int main()
{
//	freopen("input.in","r",stdin);
	cin>>n;
	for(int i=1;i<=n;i++)scanf("%d",&a[i]);
	for(int i=1;i<=n;i++)scanf("%d",&b[i]);
	if(!(n&1))
	{
		ll s=0;
		vector<int> A,B;
		for(int i=1;i<=n;i++)if(a[i]<=n/2)A.push_back(i);
		for(int i=1;i<=n;i++)if(b[i]>n/2)B.push_back(i);
		for(int i=0;i<A.size();i++)s+=abs(A[i]-B[i]);
		cout<<s;
	}
	else
	{
		ll s1=0,s2=0;
		vector<int> A,B;
		for(int i=1;i<=n;i++)if(a[i]<=n/2)A.push_back(i);
		for(int i=1;i<=n;i++)if(b[i]>n/2+1)B.push_back(i);
		for(int i=0;i<A.size();i++)s1+=abs(A[i]-B[i]);
		A.clear();B.clear();
		for(int i=1;i<=n;i++)if(a[i]<=n/2+1)A.push_back(i);
		for(int i=1;i<=n;i++)if(b[i]>n/2)B.push_back(i);
		for(int i=0;i<A.size();i++)s2+=abs(A[i]-B[i]);
		cout<<min(s1,s2);
	}
	return 0;
}
 
 
 

你可能感兴趣的:(思维,贪心)