找出创建满足 m 个条件的长度为 n 的序列 A 的多种方法。该序列 A 应仅包含非负数。每个条件由三个整数 (i,j,k) 描述,表示 max(A[i],A[j])=k。
保证序列的每个索引至少在一种情况下存在,即存在有限数量的此类序列。
n 的最大值不会超过 18,k 的最大值不会超过 20000。
我尝试使用动态编程,但时间复杂度呈指数级增长。您能建议我任何更好的方法来降低时间复杂度吗?
按照 user3386109 的建议,将每个输入约束 max(A[i], A[j]) = k 分解为三个约束:
- A[i] ≤ k
- A[j] ≤ k
- A[i] = k ∨ A[j] = k
我们可以使用类似 DPLL 的回溯过程来计算解决方案。首先,单位传播的等价:
- Given two constraints A[i] ≤ k1 and A[i] ≤ k2, we can keep A[i] ≤ min(k1, k2) and discard the other.
- Given two constraints A[i] = k1 and A[i] ≤ k2, either we can drop the latter (if k1 ≤ k2) or declare that there are no solutions (otherwise).
- Given two constraints A[i] ≤ k1 and A[i] = k2 ∨ A[j] = k2, if k1 < k2, then we can simplify the latter to A[j] = k2.
- Given two constraints A[i] = k1 and A[i] = k2 ∨ A[j] = k2, either we can drop the latter (if k1 = k2) or simplify it to A[j] = k2 (otherwise).
如果所有约束都是前两种类型,我们可以通过对非冗余不等式约束右侧的每个 k 取 (k + 1) 的乘积来计算解的数量。
否则,存在约束 A[i] = k ∨ A[j] = k。我们进行两次递归调用:一次带有额外约束 A[i] = k,另一次带有额外约束 A[i] ≤ k - 1(我们知道 A[i] > k 是不可能的)。
The depth of the recursive tree is at most n, since each child call fixes more variables than its parent after unit propagation. Hence the search tree has O(2n) nodes, each of which should be decently cheap.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)