zoukankan      html  css  js  c++  java
  • Game of Swapping Numbers —— 1G

    Game of Swapping Numbers

    题目描述

    给定两个长度为\(n\)的排列A,B\(,最大化\)\(\sum_{i = 1}^n |A_i - B_i|\),可以对\(A\)排列执行\(k\)次交换操作。

    范围

    \(n \leq 5 \times 10^5,0 \leq K \leq 10^8,-10^8 \leq A_i,B_i \leq 10^8\)

    题解

    以下是官方题解:

    最优解性质

    ​ 考虑任意一个最优解,我们把交换后的数字重新放回原来的位置,相当于为每一个元素分配了它在答案中的符号。比如 A={0, 3}, B = {1, 2},最优解符号分配是 A={-0,+3}, B={-1,+2}。

    考察符合要求的解符号分配规则,其实只要满足 A, B 中正号总和和负号总和相等,而 A、B 各自的正负号可以不一样。

    ​ 注意:有可能出现正负号和实际绝对值相反的情况,但是如果交换这一对正负号,只会使得解变优,所以在题目求最优的前提下,正负号是可以随意分配的。

    假设我们能任意指定 k 来求最优解,相当于是把 A, B 合在一起排序,取最大的 n 个填正号,最小的 n 个填符号即可。

    最少步数得到最优解

    ​ 考虑每一对元素 \(A_i,B_i\),若它们符号不同,则直接忽略这一对元素;否则,一对都是+的元素需要和一对都是-的元素进行交换才能尽快达到最优解。

    结论:n>2时,恰好 k 步与至多 k 步是等价的

    ​ 当 n>2 时,A 中一定至少存在两个 + 号或两个 - 号,此时如果我们交换这两个符号对应的数,则并不会使得原问题的解变得更劣。

    ​ n=2 需要特殊判断。

    求最优对换解

    ​ 考虑对于 A_i 和A_j,如果需要答案变优,则需要两个区间没有交,变优 2*[min(A_i,B_i) - max(A_j, B_j)]。

    ​ 将所有的 min(A_i, B_i) 和 max(A_i, B_i) 排序,依次取前 k 大相减取和即可。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 5e5 + 10;
    int a[N];
    int b[N];
    #define ll long long
    int read () {
    	int q = 0,f = 1;
    	char ch = getchar();
    	while(!isdigit(ch)) {
    		if(ch == '-')f = -1;
    		ch = getchar();
    	}
    	while(isdigit(ch)) {
    		q = q * 10 + ch - '0';
    		ch = getchar();
    	}
    	return q * f;
    }
    bool cmp(int a,int b) {
    	return a > b;
    }
    ll ans;
    
    int main () {
    	int n;int k;
    	cin >> n >> k;
    	for(int i = 1;i <= n; ++i) a[i] = read();
    	for(int i = 1;i <= n; ++i) b[i] = read();
    	for(int i = 1;i <= n; ++i) {
    		if(a[i] < b[i]) swap(a[i],b[i]);
    	}
    	sort(a + 1,a + n + 1,cmp);
    	sort(b + 1,b + n + 1,cmp);
    	for(int i = 1,j = n;i <= n and k > 0; ++i) {
    		if(a[j] < b[i]) swap(a[j],b[i]);
    		j --;
    		k --;
    	}
    	for(int i = 1;i <= n; ++i) {
    		ans += abs(a[i] - b[i]);
    	}
    	cout << ans << endl;
    	return 0;
    }
    		
    
  • 相关阅读:
    2020杭电多校第二场 1006.The Oculus
    2020杭电多校第一场 1005.Fibonacci Sum
    数论——中国剩余定理
    数论——线性同余方程
    数论——乘法逆元
    数论——裴蜀定理
    javascript预解析和作用域
    数组的排序..........加深难度
    值类型和引用类型
    js中的==和===
  • 原文地址:https://www.cnblogs.com/akoasm/p/15132683.html
Copyright © 2011-2022 走看看