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;
}
原文地址:https://www.cnblogs.com/akoasm/p/15132683.html
- 通过 JS 判断页面是否有滚动条的简单方法
- Log4j官方文档翻译(六、日志的级别)
- AngularJS API之isXXX()
- 《linux c编程指南》学习手记4
- Kibana中doc与search策略的区别
- jQuery 图片查看插件 Magnify 开发简介(仿 Windows 照片查看器)
- Log4j官方文档翻译(五、日志输出的方法)
- AngularJS API之copy深拷贝
- 光标定位,隐藏光标
- AngularJS API之toJson 对象转为JSON
- Log4j官方文档翻译(七、日志格式化)
- Log4j官方文档翻译(八、文件输出)
- 《linux c编程指南》学习手记3
- Log4j官方文档翻译(九、输出到数据库)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Linux Windows下设置定时执行任务的方法
- 详解ssh免密码登录配置方法(图示加命令)
- centos 7 修改sshd | 禁止 root登录及sshd端口脚本定义
- Linux 全能系统监控工具dstat的实例详解
- 解决-BASH: /HOME/JAVA/JDK1.8.0_221/BIN/JAVA: 权限不够问题
- linux常用工具vi/vim的使用完整版
- Linux下监视NVIDIA的GPU使用情况详解
- Linux下安装jdk1.8并配置环境变量的教程
- Linux中Homebrew的正确使用方法
- Linux中awk的使用方法详解
- Django上线部署之Apache的方法
- centos7系统下python2与python3共存
- linux把一个文件的内容复制到另一个文件的末尾
- 详解linux下nohup日志输出过大问题解决方案
- K8S dashboard 2.0 安装配置并使用 ingress-nginx 访问