有一个长为 L
正整数数组 nums
,请你从中找出 N
个数字,使得总和最大。(L <= 100w
、N <= 1w
)
注意:挑选出的任意两个数 nums[i]
、nums[j]
,需满足 a <= | i - j | <= b
(其中,0 < a < b < L
)。
svt-av1
转码不支持场景变化检测,只能固定 x
秒插入一个关键帧,容易导致:
现发现 svt-av1
支持通过 --force-key-frames
自定义哪一帧是关键帧,再通过 ffmpeg -filter:v "select='gte(scene,0)',showinfo"
输出每一帧与前一帧场景变化程度,最后找前 N
大数值,可大体解决问题。
但不加限制地随意挑选关键帧,会导致:
a
帧才能设一关键帧00:01:00
、00:02:00
……,想看个 00:01:50
还得等 50 秒),且距离关键帧远的地方质量逐渐变差。所以最好至多 b
帧要设一关键帧
这个问题可以通过动态规划来解决。我们需要找出一个算法,在满足给定的约束条件下,从数组中选择 N 个数字,使得它们的总和最大。
假设数组为
nums
,长度为L
,我们需要选择N
个数字,且任意两个选定数字的索引差满足a <= |i - j| <= b
。我们可以使用动态规划来解决这个问题。定义
dp[i][n]
表示从数组的前i
个数字中选出n
个数字的最大总和。在计算dp[i][n]
时,我们需要考虑选或不选i
位置的数字:i
位置的数字,那么dp[i][n] = dp[i-1][n]
。i
位置的数字,那么我们需要从i-a
到i-b
的范围中选出n-1
个数字的最大总和,这样dp[i][n] = nums[i] + max(dp[j][n-1])
,其中i-b <= j <= i-a
。边界条件:
dp[i][0] = 0
,表示不选任何数字,总和为 0。dp[0][n] = nums[0]
,如果n = 1
,否则为负无穷。最终结果为
max(dp[L-1][N])
。伪代码如下:
这个算法的时间复杂度为
O(L * N * (b-a))
,在给定的约束条件下是可行的。通过这种方式,我们可以找到满足条件的最大总和。