首页 > 其他分享 >[ARC120E] 1D Party 题解

[ARC120E] 1D Party 题解

时间:2023-12-04 20:25:31浏览次数:53  
标签:md 元素 int 题解 ARC120E mid MAXN max Party

提供二分+DP做法。

Solution

题意

给出 \(n(\le 2\times 10^5)\) 个单调递增偶整数 \(a_i\),求最小的 \(k\) 满足每一个 \(i\) 都可以在 \(k\) 时刻之前(含)与相邻的数相遇。每个单位时间可以移动一个单位距离。

思路

启发式思考

在想到正解之前,我们可以想想类正解。

显然,在时间一单位一单位过去的时候,一个元素如果愣着不动,肯定不是最优的策略——因为无论它去追随相邻的、或是去相遇相邻的,时间都可以尽可能更优。

所以我们看做元素是不断运动的。

如果它乱走,没有遇到任意一个相邻的元素的情况下,随便改变方向,好像也不优。所以我们也规定一个元素就只有两个阶段:第一、第二阶段——要么先左再右,要么先右再左。

想到这里,对我们有了些许启发。来看看下面这个能拿 80pts 的错解:

就考虑两种情况:

  1. 奇(ji)左偶右:黑色表示第一阶段、红色表示第二阶段

img

  1. 奇(ji)右偶左:同上

img

当然 \(n\) 的奇偶也要考虑。

像这样,是不是以为可以直接 \(O(n)\) 直接跑就解决了?

显然,这太天真了 (像我一样) ,提供一组 hack 数据:

input

10
12 12 24 26 56 70 98 124 124 178 

answer

34

output

36

至于模拟过程自己模拟吧,这是我能对出来的最小数据了。

贴一个错误代码,可以自己对拍对数据。

正解

我们可以直接二分答案 \(k\)。

接下来考虑怎么扩缩范围。

设 \(f(i,0)\) 表示元素 \(i\) 先左走,调头后最多还可走多少步。

设 \(f(i,1)\) 表示元素 \(i\) 先右走,最多可以走多少步再掉头。

然后就是小学学过的相遇问题,自己在纸上画画就出来了,这里不做赘述。要是不会的话,可以私信。

方程不好整理 (因为我懒) 自己看代码吧。挺具象的。

代码

马蜂抽象就随便看看吧,溜了

code

#include <bits/stdc++.h>
using namespace std;

#define int long long

const int MAXN = 2e5 + 5;

int n;
int a[MAXN];
int d[MAXN];
int f[MAXN][2];

bool check(int md) {
    memset(f, -1, sizeof(f));
    f[1][1] = md;
    for (int i = 2; i <= n; i++) {
        if (f[i - 1][1] != -1) {
            int k = f[i - 1][1];
            if (k - d[i] / 2 >= 0) {
                f[i][0] = max(f[i][0], md - d[i] / 2);
                f[i][1] = max(f[i][1], k - d[i] / 2);
            }
        }
        if (f[i - 1][0] != -1) {
            int k = f[i - 1][0];
            if (k - d[i] / 2 >= 0) {
                f[i][0] = max(f[i][0], k - d[i] / 2);
                f[i][1] = max(f[i][1], k - d[i] / 2);
            }
        }
    }
    return f[n][0] != -1 || f[n][1] != -1;
}

signed main() {
    scanf("%lld", &n);
    for (int i = 1; i <= n; i++) scanf("%lld", &a[i]);
    for (int i = 2; i <= n; i++) d[i] = a[i] - a[i - 1];
    int l = 1, r = 1e9, mid, ans = -1;
    while (l <= r) {
        mid = l + r >> 1;
        if (check(mid))
            r = mid - 1, ans = mid;
        else
            l = mid + 1;
    }
    printf("%lld\n", ans);
    return 0;
}

标签:md,元素,int,题解,ARC120E,mid,MAXN,max,Party
From: https://www.cnblogs.com/wang-holmes/p/17875845.html

相关文章

  • CF1695C Zero Path 题解
    题意:思路:设$minv$表示路径最小权值和,$maxv$表示路径最大权值和。当且仅当路径长度$n+m-2\equiv0\space(mod\space2)$且$minv\le0\lemaxv$时,一定有权值和为$0$的路径;否则,一定没有权值和为$0$的路径。证明:由于只能向右或向下走,路径长度......
  • CF1163B2 Cat Party (Hard Edition) 题解
    题意:思路:对于满足条件的区间$[1,x]$,有如下三种情况:$1$.所有元素出现次数都为$1$;$2$.除了一个元素出现次数为$1$之外,其余元素出现次数都相等;$3$.除了一个出现次数比其他数的出现次数多$1$的元素之外,其余元素出现次数都相等。在线处理:设$cnt_i......
  • CF1198B Welfare State 题解
    题意:有一个长度为$n$的序列$a$,给定$q$次操作,每次操作为以下两种之一:$1$.$1$$p$$x$:$a_p=x$$2$.$2$$x$:$a_i$$=$$max$$($$a_i$,$x$$)$$(1\lei\len)$求经过$q$次操作后的序列$a$。思路:$a_i$的最终值只受......
  • ABC331G 题解
    盒子里有\(n\)张\(m\)种卡片,第\(i\)种卡片有\(c_i\)张。\(\sumc_i=n\)。每次均匀随机选一张,再放回去。求拿出过的卡片包含全部种类所需要的取出次数的期望。对\(998244353\)取模。\(1\leqn,m\leq2e5,c_i\gt0\)。首先观察到,对于任意终止局面,最后取出的卡片一定......
  • CF1442D Sum 题解
    题目链接点击打开链接题目解法\(n^3\)的\(dp\)是显然的但我们没用到\(a\)不降的性质考虑一个很妙的结论:最优选法中,至多只有一个序列取了且未取满为什么?如果最优情况下,存在选且未选满的序列为\(a,b\),第一个未选的元素为\(x,y\)如果\(a_x>a_{pre_y}\),那么选\(x\)......
  • 洛谷 P1044 [NOIP2003 普及组] 栈 题解
    洛谷P1044[NOIP2003普及组]栈题解Sol本题通过分析可得:假设现在进行\(12\)次操作,我们把push认为是在地图上向右走,pop向上走,那么其中一个合法的步骤可以是(\(p1\)代表push,\(p2\)代表pop):\(p1,p1,p2,p1,p2,p2,p1,p1,p2,p2,p1,p2\)。而且我们发现,他最终会......
  • CF1692G 2^Sort 题解
    题意:思路:必要性:对于任意一个符合条件的区间$[l,r]$,任意相邻两项,满足$a_i<2*a_{i+1}(l\lei\ler-1)$。充分性:对于任意一个长度为$k+1$的区间$[l,r]$,如果任意相邻两项满足$a_i<2*a_{i+1}(l\lei\ler-1)$,那么该区间即为所求区间。......
  • CF1901 C Add, Divide and Floor 题解
    LinkCF1901CAdd,DivideandFloorQuestion给定一个长度为\(n\)的序列,每次操作你需要选择一个整数\(x\),并将所有\(a_i\)替换为\(\lfloor\frac{a_i+x}{2}\rfloor\)。求至少多少次操作后能将所有\(a_i\)变相同若最少次数小于等于\(n\),输出操作次数和每次操作所选......
  • Win11 Carla 安装教程 及 问题解决
    Win11Carla安装教程及问题解决Carlaversion:0.9.15Platform/OS:Windows11GPU:NVIDIAGeForceMX350RAM:16GBCarla下载地址:Releases·carla-simulator/carla·GitHub下载完成后解压,运行CarlaUE4.exe出现报错:Outofvideomemorytryingtoallocatearen......
  • CF1902 D Robot Queries 题解
    LinkCF1902DRobotQueriesQuestionRobot初始在\((0,0)\),有一个字符串\(s\),表示运行列表\(U\):y+1\(D\):y-1\(L\):x-1\(R\):x+1之后有\(Q\)次询问,有\(L,R,x,y\),问把运行序列的\([L,R]\)反转,Robot是否经过了点\((x,y)\)Solution显然,对于一个区间\([L,R]\)......