具有相同模块的两个顺序和最少步骤

时间:2018-07-26 04:58:40

标签: algorithm

我想要一种解决此问题的方法。
我们有两个整数序列a[1...n]b[1...n]。每次我们可以从a[1...n]中选择一个子序列(连续元素)并将x(任意数)添加到所有子序列中。我们的目标是使每个i的步数最少:a[i] = b[i] (module 5)
(5是问题标题中m的示例)
限制:

1 <= n <= 10^6
1 <= a[i],b[i] <= 10^9

例如:
a = 1 2
b = 3 4
最少:1
有可能给我一种解决方法吗?谢谢。

1 个答案:

答案 0 :(得分:0)

问题重述

  • 我们有两个整数数组ab,长度为n
  • 我们有一个模数mm = 5在您的示例中。
  • 我们的目标是更改a的值,使所有(a[i] - b[i]) % m == 0的{​​{1}}。
  • 我们希望以最少的步骤达到目标。
  • 在每个步骤中,我们向ix的所有连续元素中添加一个任意整数a[i]
  • 关于每一步可以进行多少计算,我们还没有说过。我们将尝试将其最小化,但是如果我们不得不花费二次,三次甚至是阶乘时间,那似乎是允许的。

分析

首先,请注意,通过将所有a[j]的值都设置为零并将b的每个值都调整为a[i],可以大大简化问题。然后我们只是忽略(a[i] - b[i]) % m,只考虑b取模a的值,目标变成“ m中的所有值都必须为零”。例如:

a

简化为:

m = 5
a = [1234, 5678, 9012, 3456]
b = [3141, 2718, 1414, 4242]

很显然,我们可以通过简单地分别更改每个非零值来达到目标​​。我们可以对此进行改进吗?有时。例如,这可以通过两个步骤解决:

a = [3, 0, 3, 4]

稍微复杂一点的示例需要四个步骤:

a = [2, 2, 2, 2, 0, 3]

据我所知,每当有一系列以相同数字开头和结尾的数字时,将端点全部更改为零不会有任何惩罚:

a = [2, 1, 2, 2, 1, 2, 0, 3]
   + 3, 3, 3, 3, 3, 3
a = [0, 4, 0, 0, 4, 0, 0, 3]
   do the rest individually

一步将两个数字归零。除非中间所有数字都为零,否则中间的数字不会变差,即使那样,总步数也可以是两个。

算法

尽管我无法严格证明它,但这里的算法似乎是最佳的:

a = [..., 3, ?, ?, ?, ?, ?, ?, 3, ...]
   +      2, 2, 2, 2, 2, 2, 2, 2
a = [..., 0, ?, ?, ?, ?, ?, ?, 0, ...]

示例

让我们将其应用于上面的示例数据,并查看其工作原理。

range = entire array
while true:
    move endpoints inward to skip zeroes
    if endpoints pass each other:
        everything is zero, halt
    if endpoints have equal value X:
        add (5 - X) % m to range, which will zero out endpoints
        loop
    (endpoints are unequal)
    for each endpoint:
        identify the "run" of equal numbers R at the endpoint
          (might be just one)
        skip any zeroes after the run ("after" means "inward")
        identify the next number N after the run and zeroes
    if N of endpoint x equals R of endpoint y:
        zero out the run at endpoint x
        this will set up an advantageous equal-endpoint in next step
        loop
    (neither N equaled opposite R)
    zero out whichever run is longer
    loop

该算法按预期执行了4个步骤。