CF1740C题解

众所周知,这道题的难度是 1400,所以是简单题。

分析

首先,坚信这是一道简单题,所以不要想复杂了。

首先我们需要对 aa 数组排序,这点是肯定的,为啥应该不用我解释。

下面,我们假设 p1,  p2,  p3p_1, \;p_2,\; p_3 分别为朋友在第 11 个,第 22 个和第 33 个背包中选择的棍子下标(注意,这里的下标都是指的排序后的数组下标)。我们可以发现,所有的分类情况下一定会满足下列四种条件之一:

{p1<p2<p3p1>p2>p3min(p1,p3)>p2max(p1,p3)>p2\begin{cases}p_1<p_2<p_3\\p_1>p_2>p_3\\\min(p_1,p_3)>p_2\\\max(p_1,p_3)>p_2\\\end{cases}

翻译一下,这四种情况的答案分别是:

ans={(ap2ap1)+(ap3ap2)ifp1<p2<p3(ap3ap2)+(ap2ap1)ifp1>p2>p3(ap1ap2)+(ap3ap2)ifmin(p1,p3)>p2(ap2ap3)+(ap2ap1)ifmax(p1,p3)<p2ans=\begin{cases}(a_{p2}-a_{p1})+(a_{p3}-a_{p2})\operatorname{if} p_1<p_2<p_3\\(a_{p3}-a_{p2})+(a_{p2}-a_{p1})\operatorname{if} p_1>p_2>p_3\\(a_{p1}-a_{p2})+(a_{p3} -a_{p2})\operatorname{if}\min(p_1,p_3)>p_2\\(a_{p2}-a_{p3})+(a_{p2} -a_{p1})\operatorname{if}\max(p_1,p_3)<p_2\\\end{cases}

你感性理解一下,你就会发现前两种情况一定不会比后两种优(因为如果出现这两种情况,你只需要将其中两个背包交换一下位置就会转化为后面两种,而明显转化后会更优,这个你自己手模一下应该很显然),于是我们就只用考虑后面两种情况就可以了,即:

ans={(ap1ap2)+(ap3ap2)ifmin(p1,p3)>p2(ap2ap3)+(ap2ap1)ifmax(p1,p3)<p2ans=\begin{cases}(a_{p1}-a_{p2})+(a_{p3}-a_{p2})\operatorname{if}\min(p_1,p_3)>p_2\\(a_{p2}-a_{p3})+(a_{p2} -a_{p1})\operatorname{if}\max(p_1,p_3)<p_2\\\end{cases}

但是你会发现,即使是这样,我们任然不能很好的限制计算方法,于是我们考虑继续加强条件。

下面我们以第三种情况为例加强限制(第四种的推理过程是一样的):

我们假设有 min(p1,  p3)>p2+1\min(p_1,\;p_3) > p_2 + 1(注意这里的都是下标之间的关系),我们分下列三种情况分析(注意,我们下面的讨论都基于我们假设朋友一定会选 p1,  p2,  p3p_1,\;p_2,\;p_3 的基础上):

  1. 如果 p2+1p_2 + 1 这根棍子被放在了第 11 个背包中,那么朋友在背包 1 1 中选择下标为 p2+1p_2 + 1 的棍子而不是 p1p_1,因为 ap2+1ap2ap1ap2a_{p_2 + 1} - a_{p_2} \leqslant a_{p_1} - a_{p_2},因此假设不成立;
  2. 如果 p2+1p_2 + 1 这根棍子被放在了第 22 个背包中,那么朋友在背包 2 2 中选择下标为 p2+1p_2 + 1 的棍子而不是 p2p_2,因为 (ap1ap2+1)+(ap3ap2+1)(ap1ap2)+(ap3ap2) (a_{p_1} - a_{p_2 + 1}) + (a_{p_3} - a_{p_2 + 1}) \leqslant (a_{p_1} - a_{p_2}) + (a_{p_3} - a_{p_2} ),因此假设不成立;
  3. 如果 p2+1p_2 + 1 这根棍子被放在了第 33 个背包中,那么朋友在背包 3 3 中选择下标为 p2+1p_2 + 1 的棍子而不是 p3p_3,因为 ap2+1ap2ap3ap2a_{p_2 + 1} - a_{p_2} \leqslant a_{p_3} - a_{p_2},因此假设不成立。

于是我们发现,在 min(p1,  p3)>p2+1\min(p_1,\;p_3) > p_2 + 1 时,朋友一定不会选择我们给他“指定”的那三个棍子,于是我们把条件收束为:

ans={min(p1,p3)>p2&min(p1,p3)=p2+1max(p1,p3)<p2&max(p1,p3)=p21ans=\begin{cases}\min(p_1,p_3)>p_2 \& \min(p_1,p_3)=p_2+1\\\max(p_1,p_3)<p_2 \& \max(p_1,p_3)=p_2-1\\\end{cases}

的时候我们才能确定朋友所选取的棍子就是我们“指定”的那三根。

这个条件化简一下其实就是:

ans={min(p1,p3)=p2+1max(p1,p3)=p21ans=\begin{cases}\min(p_1,p_3)=p_2+1\\\max(p_1,p_3)=p_2-1\\\end{cases}

而我们需要最大化 ap2ap1+ap3ap2|a_{p_2}-a_{p_1}|+|a_{p_3} - a_{p_2}|,于是我们很显然将 min(p1,  p3)\min(p_1,\;p_3) 定为 11 或者让 max(p1,  p3)\max(p_1,\;p_3)nn,这样我们得到的解一定最优(注意此时我们是在计算答案,这里的 min 和 max 与上式中并不表同一含义,具体看下面的式子)。但是此时我们也只是确定了其中一边的取值,那么另一边枚举就行了,于是我们有以下计算式:

ans=max{maxi=3n{(aia1)+(aiai1)}此时的排列是1,i n,2 i-1maxi=3n2{(anai)+(ai+1ai)}此时的排列是n,1 i,i+1 n-1ans=\max\begin{cases}\max^n_{i=3}\{(a_i-a_1)+(a_i-a_{i-1})\}\text{此时的排列是1,i~n,2~i-1} \\\max^{n-2}_{i=3}\{(a_n-a_i)+(a_{i+1}-a_{i})\}\text{此时的排列是n,1~i,i+1~n-1} \\\end{cases}

于是我们就做完了,对就是这么简单,区区 1400 而已,是真的不能把他想的太难了,不然真的很容易想偏。

附源码:

#include<bits/stdc++.h>
using namespace std;
int t;
int a[10000];
int main(){
	cin>>t;
	while(t--){
		int n;
		cin>>n;
		for(int i=1;i<=n;i++){
			cin>>a[i];
		}
		sort(a+1,a+n+1);
		int ans=0;
		for(int i=3;i<=n;i++){
			ans=max(ans,a[i]-a[1]+a[i]-a[i-1]);//1,i~n,2~i-1
		}
		for(int i=1;i<=n-2;i++){
			ans=max(ans,a[n]-a[i]+a[i+1]-a[i]);//n,1~i,i+1~n-1
		}
		printf("%d\n", ans);
	}
	return 0;
}
posted @   KK_SpongeBob  阅读(4)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 百万级群聊的设计实践
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
· .NET 10 首个预览版发布,跨平台开发与性能全面提升
· 《HelloGitHub》第 107 期
点击右上角即可分享
微信分享提示