总和可被k整除的最长子序列[关闭]

Posted

技术标签:

【中文标题】总和可被k整除的最长子序列[关闭]【英文标题】:Longest subsequence whose sum is divisible by k [closed] 【发布时间】:2020-07-29 08:01:25 【问题描述】:

我在练习一些动态规划问题,遇到了这个问题

给定一个 n(1<=n<=1000) 整数数组和一个正整数 k(k<=1000)。求和能被k整除的最长子序列。

例如,a = [1,6,11,5,10,15,20,2,4,9]k=5

结果应该是:[9,4,20,15,10,5,11,6] 因为9+4+20+15+10+5+11+6 = 80 可以被 5 整除。

什么是解决这个问题的合适方法?

【问题讨论】:

请阅读:How do I ask a good question? 所以我们可以假设它没有连续嵌入到数组中? 似乎是子集和问题。把所有的数字加起来。总数是 83。那么问题就变成了,“有没有一个总和为 3 的子集?”在示例中,子集 1,2 存在并且我们完成了。如果没有子集总和为 3,那么您需要尝试 8,然后是 13,然后是 18,等等。 【参考方案1】:

从可能的最长子序列开始,即数组本身。计算其和模 k。如果它为零,我们就完成了。否则,找到一个数,使得它的模 k 相同。如果存在,请将其删除,我们就完成了。否则继续。

【讨论】:

如果找不到具有相同模数的数字,则您的算法不明确。 @Mansoor OP 要求方法,而不是完整的解决方案。 同意,只是一个注释。【参考方案2】:

蛮力方法:

我们可以生成所有可能的子序列,然后找到其中最大的子序列,其和可以被K整除。

但是,这种方法的时间复杂度将是O(n*n)

高效方法:

我们可以在这里使用动态规划。请注意,此方法仅适用于 K 的小值。

dp[i][curr_mod] = max(dp[i + 1][curr_mod], dp[i + 1][(curr_mod + arr[i]) % m] + 1)

这里,dp[i][curr_mod] 存储子数组arr[i…N-1] 的最长子序列,使得该子序列和curr_mod 之和可以被K 整除。

在每个步骤中,可以选择index i 更新curr_mod,也可以忽略它。

另外,请注意,只需要存储 SUM % m 而不是整个总和,因为此信息足以完成 DP 的状态。

【讨论】:

以上是关于总和可被k整除的最长子序列[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

数字总和可被 K 整除的子数组的数量

给定一个数组,打印所有可能的连续子序列,其总和可被给定数 x 整除

最长递增子序列

HDU - 6197 array array array (最长上升子序列&最长下降子序列)

codevs 1862 最长公共子序列(求最长公共子序列长度并统计最长公共子序列的个数)

最长公共子串与最长公共子序列之间的关系