1450F The Struggling Contestant(贪心+思维)

Codeforces Global Round 12

F. The Struggling Contestant

题面:The Struggling Contestant

题意:有一个长度为 nnn 的序列 arrarrarr,其序号 ppp 分别为 1...n1...n1...n,现在需要对其进行重新排列,使得最终的序列满足 arr[i]≠arr[i+1],1≤i<narr[i] \ne arr[i+1],1\le i < narr[i]​=arr[i+1],1≤i<n 的最小 “跨度” 是多少,一个排列的 ”跨度“ 定义为满足 ∣pi−pi+1∣>1,1≤i<n|p_i-p_{i+1}| > 1,1\le i < n∣pi​−pi+1​∣>1,1≤i<n 的 iii 的数量。

范围:1≤n≤1e5,1≤ai≤n1 \le n \le 1e5, 1 \le a_i \le n1≤n≤1e5,1≤ai​≤n。

分析: 显然在初始状态下面的 ”跨度“ 最小,我们应该尽可能少的改变当前序列的相对顺序,但是如果存在了数字相同的相邻元素,那么就必须进行额外操作。假设数组中只存在两个数字相同并且这两个数字相邻,比如 123341233412334,这个时候我们要把 333333 拆开,最优的是 341233412334123,即将 343434 一起移动。进一步分析可以发现除了相邻的相同数字,其他的数字都不需要单独进行操作,整段整段地移动就好了。因此我们可以根据相邻元素是否相同把数组分割成若干段,每段只需要关注两个端点,那么现在的问题就转换为如何重新排序与分割这些段来获取答案。

定义当前序列中 f(x)f(x)f(x) 为 xxx 作为端点出现的次数,如果左右端点为一个点的话需要计算两次。

当前的局面下存在可行解的条件为 max(f(x))≤k+2max(f(x)) \le k + 2max(f(x))≤k+2,kkk 表示相邻相同数字对的数量,证明如下:

  1. 当前有 k+1k+1k+1 个段,共 2k+22k+22k+2 个端点,除去左右 222 个独立的端点,中间还剩下 2k2k2k 个相邻的点,最多只能选择其中 kkk 个点,因此 f(x)f(x)f(x) 最大为 k+2k + 2k+2。
  2. 现在证明 max(f(x))≤k+2max(f(x)) \le k+2max(f(x))≤k+2 一定可以构造出一个解。假设 xxx 为出现次数最多的数,选择一段以 xxx 为端点的段,再选择一段以 y≠xy \ne xy​=x 为端点的段,让 xxx 与 yyy 相邻将两段融合为一个新的段,此时 k,f(x),f(y)k,f(x),f(y)k,f(x),f(y) 均减一,f(x),f(y)≤k+2f(x),f(y) \le k+2f(x),f(y)≤k+2 仍然满足。对于 z≠x≠yz \ne x \ne yz​=x​=y,在融合 x,yx,yx,y 之前 f(z)≤2k+2−f(x)≤2k+2−f(z)f(z) \le 2k+2-f(x) \le 2k+2-f(z)f(z)≤2k+2−f(x)≤2k+2−f(z),即 f(z)≤k+1f(z) \le k+1f(z)≤k+1,在融合 x,yx,yx,y 之后 kkk 减一,f(z)≤k+2f(z) \le k+2f(z)≤k+2 仍然满足。这样,每次将 kkk 减一直到 000,构造完毕,操作次数为 kkk。

现在考虑 max(f(x))>k+2max(f(x)) > k+2max(f(x))>k+2 的情况,之前都是把一整段看做整体,现在考虑如何通过切割段使得 max(f(x))≤k+2max(f(x)) \le k+2max(f(x))≤k+2 满足,从而得到答案。

如果我们在切割的位置左右两个元素中包含了 xxx,那么会导致 f(x),kf(x),kf(x),k 均增加,max(f(x))>k+2max(f(x)) > k+2max(f(x))>k+2 的情况不会改变。所以我们需在要两个元素 y≠x,z≠xy\ne x,z \ne xy​=x,z​=x 中间进行分割,这样会导致 kkk 增加,重复这样的过程直到 max(f(x))≤k+2max(f(x)) \le k+2max(f(x))≤k+2,操作次数为 max(f(x))−(k+2)max(f(x)) - (k + 2)max(f(x))−(k+2)。

注意最多只会存在一个 xxx 满足 f(x)>k+2f(x) > k+2f(x)>k+2。

因此最终的答案为 k+max(0,max(f(x))−(k+2))k + max(0, max(f(x)) - (k + 2))k+max(0,max(f(x))−(k+2))。

Code

#include <bits/stdc++.h>
#define int long long
#define double long double
using namespace std;inline int read()
{int s = 0, w = 1;char ch = getchar();while (ch < '0' || ch > '9'){if (ch == '-')w = -1;ch = getchar();}while (ch >= '0' && ch <= '9')s = s * 10 + ch - '0', ch = getchar();return s * w;
}const int MAXN = 1e5 + 10;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const double eps = 1e-9;
const double PI = acos(-1.0);int n, m, k;int arr[MAXN];int cnt[MAXN], num[MAXN];signed main()
{int T = read();while (T--){n = read();for (int i = 0; i <= n; i++){cnt[i] = num[i] = 0;}int k = 0;for (int i = 0; i < n; i++){arr[i] = read();num[arr[i]]++;if (i && arr[i] == arr[i - 1]){k++;cnt[arr[i]] += 2;}}cnt[arr[0]]++, cnt[arr[n - 1]]++;int max_cnt = 0, max_num = 0;for (int i = 1; i <= n; i++){max_cnt = max(max_cnt, cnt[i]);max_num = max(max_num, num[i]);}if (max_num * 2 > n + 1) cout << -1 << endl;else cout << k + max(0ll, max_cnt - (k + 2)) << endl;}return 0;
}

【END】感谢观看

1450F The Struggling Contestant(贪心+思维)相关推荐

  1. 贪心/思维题 UVA 11292 The Dragon of Loowater

    题目传送门 1 /* 2 题意:n个头,m个士兵,问能否砍掉n个头 3 贪心/思维题:两个数组升序排序,用最弱的士兵砍掉当前的头 4 */ 5 #include <cstdio> 6 #i ...

  2. cf:B. Patchouli‘s Magical Talisman【数学贪心思维 + 奇偶分析】

    分析 给出一堆数 可以通过相加或除2让它们全部变成奇数 如果全奇数返回0 由于奇数 + 偶数 = 奇数 所以只要有一个奇数就能把偶数和它相加不停的变成奇数 所以只要存在奇数,就可以返回偶数的个数 否则 ...

  3. 《C语言程序设计实践》————如何买玫瑰?(贪心思维)

    <C语言程序设计实践>----如何买玫瑰?(贪心思维) 要求:小慧过生日,小明要买玫瑰送她.每枝红玫瑰5元,满5支送1枝,满20枝送5枝.小明一共有n(n>10)元钱,最多能买到多少 ...

  4. HDU - 5242 Game(树形dp+树链剖分/树上贪心+思维)

    题目链接:点击查看 题目大意:给出一棵包含n个节点的树,每个节点都有一个权值,整棵树的根是点1,问从点1开始向下一直走到叶子节点,可以走k次,怎么样走权值和最大,每个节点被走过一次后权值会变为0 题目 ...

  5. ZOJ 3829 贪心 思维题

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3829 现场做这道题的时候,感觉是思维题.自己智商不够.不敢搞,想着队友智商 ...

  6. 牛客 - 共鸣问题(贪心+思维)

    题目链接:点击查看 题目大意:给出 nnn 个点,每个点都有点权,再给出 mmm 个关系,以 (x,y,z)(x,y,z)(x,y,z) 的形式给出,规定如下: 同时选择点 xxx 和点 yyy 将获 ...

  7. POJ - 1328 Radar Installation(贪心+思维)

    题目链接:点击查看 题目大意:校长想通过监控设备覆盖学校内的N座建筑物,每座建筑物被视作一个质点,在笛卡尔坐标系中给出他们的坐标(x,y),并且所有建筑物均处在x轴的上方.因为学校的供电和传输线路均沿 ...

  8. CodeForces - 353E Antichain(贪心+思维)

    题目链接:点击查看 题目大意:给出n个点,用n-1条边连接,第i条边连接着点i与点(i+1)%n,也就是首尾相接组成了一个环,现在0表示点i连到点(i+1)%n的一条有向边,1表示点(i+1)%n连到 ...

  9. Dreamoon Likes Coloring CodeForces - 1330C(贪心+思维)

    Dreamoon likes coloring cells very much. There is a row of n cells. Initially, all cells are empty ( ...

最新文章

  1. python文件流习题解析
  2. linux系统编程:自己动手写一个who命令
  3. ASP.NET Core 1.0 开发记录
  4. 如何为你的博客园添加到百度统计
  5. 华水c语言课程设计,【图片】发几个C语言课程设计源代码(恭喜自己当上技术小吧主)【东华理工大学吧】_百度贴吧...
  6. Atitit 技术管理项目管理的职责列表attilax总结 v2 r74 brch4com.docx
  7. A Game with Traps—— 二分
  8. 在线框架引用|bootstrap|jq|jqmobile|CSS框架_无需整理
  9. MNN源码阅读之模型转换
  10. 超出本地计算机网络,超出本地计算机网络适配器卡的名称限制怎么解决?
  11. django前戏准备
  12. 在线免费学习java资源推荐
  13. 思维题:三个箱子,一个只装苹果,一个只装橙,另一个装苹果和橙,请问?
  14. 运用深度学习进行文本生成
  15. Adobe Illustrator AI撤回和取消撤回
  16. 大疆M210 V2+妙算2-G+LIVOX MID-40使用记录
  17. [opencv][cpp] 学习手册3:多边形拟合
  18. php watcher,vue 中的 watcher详解
  19. fenix3 hr 中文说明书_fenix3 中英文对照说明书.pdf
  20. b5对战平台服务器位置,csgob5对战平台

热门文章

  1. 你并没有那么去努力 所以你不能怪生活
  2. cass简码大全_CASS简码与实体编码对照表
  3. qt中glMultiTexCoord2fARB报错
  4. [面试题]1000瓶水中有1瓶是有毒的,问需要多少只老鼠才能试出那瓶有毒?
  5. IndProp章节中pumping lemma的证明
  6. 崩坏3服务器维护2月8号,崩坏3 8月29日更新官方公告
  7. 华为mate9安装Fiddler证书
  8. 在Python中以foo.bar.baz的方式访问嵌套dict中的内容
  9. Steaming SQL for Apache Kafka 学习
  10. linux下没有yum命令,linux下配置yum的三种方法与yum命令详解