最长子序列,其和可被k整除

时间:2020-07-29 08:01:25

标签: c++ algorithm sum dynamic-programming subsequence

我正在练习一些动态编程问题,并且遇到了这个问题

给出一个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整除。

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

2 个答案:

答案 0 :(得分: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的状态。

答案 1 :(得分:1)

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

相关问题