zoukankan      html  css  js  c++  java
  • ABC128F Frog Jump

    题目链接

    题目大意

    给定一个长为 $n$ 的数组 $s$,下标从 $0$ 开始。$ 3 le n le 105$,$-109 le s_i le 10^9$,$s_0 = s_{n - 1} = 0$ 。

    一只青蛙要在数组 $s$ 上玩一个游戏。游戏规则如下
    初始时青蛙的位置(即青蛙所在的数组下标)是 $0$,它的分数是 $0$;青蛙要选择两个正整数 $A,B$,并不断重复下述过程直到游戏结束:
    step 1. 设青蛙当前位置是 $x$,跳到 $y = x + A$ 。若 $y = n -1$,游戏结束;若 $y$ 超出下标范围或者青蛙之前到过位置 $y$,则游戏结束,分数是 $-infty$;否则分数加上 $s_{y}$,进行 step 2。
    step 2. 设青蛙当前位置是 $x$,跳到 $y = x - B$ 。 若 $y = n -1$,游戏结束;若 $y$ 超出下标范围或者青蛙之前到过位置 $y$,则游戏结束,分数是 $-infty$;否则分数加上 $s_{y}$,回到 step 1。

    试问青蛙的游戏得分最大可能是多少?

    分析

    比赛时我把题意误解成每次选择 step 1 或 step 2 其中之一进行操作。

    $A = n - 1$ 是平凡情形,考虑青蛙至少跳两步且得分不是 $-infty$ 的情形。
    此时有(i) $ 1 le B < A le n - 2$;(ii)青蛙的位置序列是 $0, A, A - B, (A - B) + A, 2(A- B), 2(A- B) + A, dots, k(A- B), k(A-B) + A = n - 1$,且序列中无重复元素。

    key observation

    这个序列可以分解成两部分,从左往右,$0, A - B, 2(A-B), dots, k(A-B)$;从右往左,$n - 1 = k(A - B) + A, n - 1 -(A-B), n- 1- 2(A-B), dots, n - 1 - k(A- B) = A$ 。
    换言之,青蛙的位置序列可以分解成两个由数组 $s$ 的下标构成的不相交(即无共同元素)的等差序列,一个从左往右,首项是 0,公差是 $A - B$;另一个是从右往左,首项是 $n - 1$,公差是 $B - A$ 。

    容易看出,青蛙的位置序列完全由 $A - B$ 和 $k$ 决定。于是我们可以得到一个解法:

    枚举 $A - B$ 的值;固定 $A-B$,再枚举 $k$ 的值,若两等差序列无共同元素,则更新答案。

  • 相关阅读:
    php 替换二维数组的 key
    全选功能
    向数组中添加含有下标的元素
    判断一个进程是否在执行中
    初识 Nginx
    原生JS中DOM节点相关API合集
    工作中经常用到github上优秀、实用、轻量级、无依赖的插件和库
    Unsupported major.minor version ... JDK具体对应版本
    Scala常用命令
    使用nexus搭建maven私服教程详解
  • 原文地址:https://www.cnblogs.com/Patt/p/10959103.html
Copyright © 2011-2022 走看看