我想要一种解决此问题的方法。
我们有两个整数序列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
有可能给我一种解决方法吗?谢谢。
答案 0 :(得分:0)
a
和b
,长度为n
。m
; m = 5
在您的示例中。a
的值,使所有(a[i] - b[i]) % m == 0
的{{1}}。i
至x
的所有连续元素中添加一个任意整数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个步骤。