总和可被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整除的最长子序列[关闭]的主要内容,如果未能解决你的问题,请参考以下文章
给定一个数组,打印所有可能的连续子序列,其总和可被给定数 x 整除
HDU - 6197 array array array (最长上升子序列&最长下降子序列)