F. Make k Equal

题目链接

题意

长度为n的序列,每次可以选择一个最大的数字将其减一或者选择一个最小的数字将其加一,问最少操作多少次可以使得序列中至少存在 k 个一样的数字

分析

官方题解:http://codeforces.com/blog/entry/75246

可以想到最后一样的数字,一定是在原序列里面出现的,所以将原数组离散化之后,枚举最后一样的数字,并努力把它凑够 k 个。如何凑?借助左侧或者右侧的数字。只要借助了某侧的数字,那么这一侧全部的数字都要先挪动它旁边的那个位置,然后再按照需要搬到当前这个位置上来。

所以最后只会有两种方案:优先选左侧或者优先选右侧,我们都试一下就好了,结果取最小(计算细节可以参考代码以及官方题解)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
#define dbg(x...) do { cout << "\033[32;1m" << #x <<" -> "; err(x); } while (0)
void err() { cout << "\033[39;0m" << endl; }
template<class T, class... Ts> void err(const T& arg,const Ts&... args) { cout << arg << " "; err(args...); }
const int N = 200000 + 5;
int n, k, a[N];
vector<int> v;
ll cnt[N], sum[N];
ll pre[N]; int main(){
scanf("%d%d", &n, &k);
for(int i=1;i<=n;i++){
scanf("%d", &a[i]);
v.push_back(a[i]);
}
v.push_back(0);
sort(v.begin(),v.end());v.erase(unique(v.begin(),v.end()),v.end());
for(int i=1;i<=n;i++){
int id = lower_bound(v.begin(),v.end(),a[i]) - v.begin();
cnt[id] ++;
}
n = v.size()-1;
for(int i=1;i<=n;i++) {
sum[i] = sum[i-1] + cnt[i];
pre[i] = pre[i-1] + cnt[i] * v[i];
}
ll res = pre[n];
for(int i=1;i<=n;i++){
ll need = max(0ll, k - cnt[i]);
// 先左后右
{
ll tmp = 0;
int lnum = min(need, sum[i-1]);
// 只有当lnum>0时才需要计算,下面同理
if(lnum){
tmp = sum[i-1] * (v[i]-1) - pre[i-1];
tmp += lnum;
}
int rnum = min(need-lnum, sum[n] - sum[i]);
if(rnum){
tmp += (pre[n] - pre[i]) - (sum[n]-sum[i]) * (v[i]+1);
tmp += rnum;
}
res = min(res, tmp);
}
// 先右后左
{
ll tmp = 0;
int rnum = min(need, sum[n] - sum[i]);
if(rnum){
tmp = (pre[n] - pre[i]) - (sum[n] - sum[i]) * (v[i]+1);
tmp += rnum;
}
int lnum = min(need-rnum, sum[i-1]);
if(lnum){
tmp += sum[i-1] * (v[i]-1) - pre[i-1];
tmp += lnum;
}
res = min(res, tmp);
}
}
cout << res << endl;
return 0;
}

2400难度的题目,平常心看待就好了

CF-1328 F. Make k Equal的更多相关文章

  1. hdu 1588 求f(b) +f(k+b) +f(2k+b) +f((n-1)k +b) 之和 (矩阵快速幂)

    g(i)=k*i+b; 0<=i<nf(0)=0f(1)=1f(n)=f(n-1)+f(n-2) (n>=2)求f(b) +f(k+b) +f(2*k+b) +f((n-1)*k + ...

  2. CF 633 F. The Chocolate Spree 树形dp

    题目链接 CF 633 F. The Chocolate Spree 题解 维护子数答案 子数直径 子数最远点 单子数最长直径 (最长的 最远点+一条链) 讨论转移 代码 #include<ve ...

  3. 698. Partition to K Equal Sum Subsets 数组分成和相同的k组

    [抄题]: Given an array of integers nums and a positive integer k, find whether it's possible to divide ...

  4. CF 494 F. Abbreviation(动态规划)

    题目链接:[http://codeforces.com/contest/1003/problem/F] 题意:给出一个n字符串,这些字符串按顺序组成一个文本,字符串之间用空格隔开,文本的大小是字母+空 ...

  5. [LeetCode] Partition to K Equal Sum Subsets 分割K个等和的子集

    Given an array of integers nums and a positive integer k, find whether it's possible to divide this ...

  6. [Swift]LeetCode698. 划分为k个相等的子集 | Partition to K Equal Sum Subsets

    Given an array of integers nums and a positive integer k, find whether it's possible to divide this ...

  7. 698. Partition to K Equal Sum Subsets

    Given an array of integers nums and a positive integer k, find whether it's possible to divide this ...

  8. CF 1138 F. Cooperative Game

    F. Cooperative Game 链接 题意: 有10个玩家,开始所有玩家在home处,每次可以让一些玩家沿着边前进一步,要求在3(t+c)步以内,到达终点. 分析: 很有意思的一道题.我们构造 ...

  9. CF 1041 F. Ray in the tube

    F. Ray in the tube 链接 题意: 有两条平行于x轴的直线A,B,每条直线上的某些位置有传感器.你需要确定A,B轴上任意两个整点位置$x_a$,$x_b$,使得一条光线沿$x_a→x_ ...

随机推荐

  1. VMware 16.1虚拟机安装

    VMware 16.1创建虚拟机 1.1首先打开我们安装好的VMware点击创建新的虚拟机 典型为自动安装,接口位默认 自定义安装更自由,可以把按需求选择 VMware16版本,只能选择Worksta ...

  2. Ubuntu上好用的截图工具——flameshot

    前言   堪称完美的截图工具--flameshot,windows上人们习惯性的使用QQ自带的截图工具Ctrl+Alt+A或者WeChat自带的截图工具Alt+A,若您是一位使用聊天工具截图多年的&q ...

  3. Java实现开根号运算(不使用数组和String)

    使用Java自己实现开根号运算,网上也有不少代码,多数都使用String或者数组.这里写一段只使用double基础数据类型实现的方法. private static double sqrt(int n ...

  4. Hbase Region合并

    业务场景: Kafka+SparkStreaming+Hbase由于数据大量的迁移,再加上业务的改动,新增了很多表,导致rerigon总数接近4万(36个节点) 组件版本: Kafka:2.1.1 S ...

  5. dd命令的详细介绍

    1.命令简介  dd 的主要选项: 指定数字的地方若以下列字符结尾乘以相应的数字: b=512, c=1, k=1024, w=2, xm=number m if=file #输入文件名,缺省为标准输 ...

  6. poj-DNA排序

    描述 现在有一些长度相等的DNA串(只由ACGT四个字母组成),请将它们按照逆序对的数量多少排序. 逆序对指的是字符串A中的两个字符A[i].A[j],具有i < j 且 A[i] > A ...

  7. disfunc绕过

    绕过DisFunc的常见小技巧 解析webshell命令不能执行时的三大情况 一是 php.ini 中用 disable_functions 指示器禁用了 system().exec() 等等这类命令 ...

  8. 入门OJ:简单的网络游戏

    题目描述 在某款极具技术含量的网络游戏中,佳佳靠着他的聪明智慧垄断了游戏中的油田系统.油田里有许多油井,这些油井排成一个M*N的矩形.每个油井都有一个固定的采油量.每两个相邻的油井之间有一条公路,这些 ...

  9. 部署自动初始化Schema的数据库

    我们使用容器的方式部署数据库组件,特别是企业有大量的项目开发业务的,部署的开发.测试数据库组件较多时.经常会遇到以下问题: 业务需要使用数据库,但部署完数据库后,需要在数据库中执行创建schema的操 ...

  10. PCB导线长宽与电源压降

    为了计算PCB中电源线走线后的压降,需要知道PCB中使用的铜的电阻率, PCB板中的铜是直接贴上去的铜箔,因此可以当成纯铜(我问了PCB打样的厂家他们的铜的电阻率,但是他们给我说不知道,所以干脆就当成 ...