2021牛客多校第一场G

题意:

给你两个长度均为n的序列ai,bi,要求你交换的一个序列K次使得 在这里插入图片描述值最大。

 啊,这个贪心,真的好难想

首先,我们先不考虑交换,计算abs(ai-bi)的和,然后如果我们要将ai,bi,aj,bj进行一次交换,也就是将

max(ai,bi)-min(ai,bi)+max(aj,bj)-min(aj,bj)

变成

max(ai,bi)-min(aj,bj)+min(ai,bi)-max(aj,bj)

 那么就需要在原来的sum上加上2*(min(ai,bi)-max(aj,bj))

所以要使这k次所增加的效益最大,排两次序,就依次用最大的min(ai,bi)减去最小的max(aj,bj),直至将k次用完或者,加上的这个数<=0(敲重点!!!!)

因为在n>2的时候,总可以找到一对交换但不影响结果的情况

所以在n>2时,恰好k次和至多k次是一样的,n=2单独考虑就行

emmm

思路想清楚就发现很简单

代码:

#include <bits/stdc++.h>
using namespace std;
const int N = 500010;
int a[N], b[N];
int mi[N], ma[N];

typedef long long ll;

bool cmp1(int x, int y)
{
	return x > y;
}
bool cmp2(int x, int y)
{
	return x < y;
}

int main()
{
	int n, k;
	cin >> n >> k;
	ll sum = 0;
	for (int i = 0; i < n; i++)
	{
		cin >> a[i];
	}
	for (int i = 0; i < n; i++)
	{
		cin >> b[i];
	}
	if(n==2) 
	{
		if(k>=1)
		{
			sum=max(abs(a[0]-b[1])+abs(a[1]-b[0]),abs(a[0]-b[0])+abs(a[1]-b[1]));
		}
		else
		{
			sum=abs(a[0]-b[0])+abs(a[1]-b[1]);
		}
		cout<<sum<<endl;
		return 0;
	}
	for (int i = 0; i < n; i++)
	{
		mi[i] = min(a[i], b[i]);
		ma[i] = max(a[i], b[i]);
		sum += abs(a[i]-b[i]);
	}
	sort(mi, mi + n, cmp1);
	sort(ma, ma + n, cmp2);
	for (int i = 0; i <k; i++)
	{
		if (mi[i] - ma[i] <= 0)
		{
			break;
		}
		sum += 2 * (mi[i]-ma[i]);
	}
	cout << sum << endl;
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值