algorithm - 计算 A 的子序列的数量,使得子序列的每个元素都可以被它的索引整除(从 1 开始)
问题描述
B 是 A 的子序列当且仅当我们可以通过删除零个或多个元素将 A 变为 B。
A = [1,2,3,4]
B = [1,4] is a subsequence of A.(Just remove 2 and 4).
B = [4,1] is not a subsequence of A.
计算满足此条件的 A 的所有子序列:A[i]%i = 0
请注意,i
从 1而不是 0 开始。
例子 :
Input :
5
2 2 1 22 14
Output:
13
所有这 13 个子序列都满足 B[i]%i = 0 条件。
{2},{2,2},{2,22},{2,14},{2},{2,22},{2,14},{1},{1,22},{1 ,14},{22},{22,14},{14}
我的尝试:
我能想出的唯一解决方案很O(n^2)
复杂。
解决方案
假设 中的最大元素A
为C
,以下是具有时间复杂度的算法O(n * sqrt(C))
:
- 对于 中的每个元素
x
,A
找到 的所有除数x
。 - 对于
i
从 1 到的每一个,使用步骤 1 的结果n
找到每一个是 的倍数的j
这样。A[j]
i
- 对于每一个
i
从 1 到n
和j
这样A[j]
的倍数i
(使用步骤 2 的结果),找到B
具有i
元素的数量并且最后一个元素是A[j]
(动态规划)。
def find_factors(x):
"""Returns all factors of x"""
for i in range(1, int(x ** 0.5) + 1):
if x % i == 0:
yield i
if i != x // i:
yield x // i
def solve(a):
"""Returns the answer for a"""
n = len(a)
# b[i] contains every j such that a[j] is a multiple of i+1.
b = [[] for i in range(n)]
for i, x in enumerate(a):
for factor in find_factors(x):
if factor <= n:
b[factor - 1].append(i)
# There are dp[i][j] sub arrays of A of length (i+1) ending at b[i][j]
dp = [[] for i in range(n)]
dp[0] = [1] * n
for i in range(1, n):
k = x = 0
for j in b[i]:
while k < len(b[i - 1]) and b[i - 1][k] < j:
x += dp[i - 1][k]
k += 1
dp[i].append(x)
return sum(sum(dpi) for dpi in dp)
推荐阅读
- firebase - 如何使用开放规则启动 Firebase 实时数据库模拟器?
- python - 如何在迭代时从嵌套列表创建垂直列表
- azure - 使用设备客户端和使用 HTTP DELETE 的设备预配服务在 azure iot hub 中删除(取消预配)设备
- data-visualization - Amcharts 水平条形图标签问题
- python - 混淆我的 DL 模型和 Python 的最佳方法?
- scala - Scala Option 获取键值
- java - 例外:期待菜单,得到 androidx.constraintlayout.widget.ContstraintLayout
- sql - SQL 创建三个表并与之交互
- amazon-web-services - ECS 可以在单独的帐户中访问 ECR
- html - 如何为网格中的各个列着色