📌  相关文章
📜  最长子序列,其总和可被给定数整除(1)

📅  最后修改于: 2023-12-03 15:10:37.722000             🧑  作者: Mango

最长子序列,其总和可被给定数整除

问题描述

给定一个整数数组和一个整数k,找到最长的子序列,使其总和可以被k整除。返回子序列的长度,如果不存在这样的子序列,则返回0。

解决方案
Brute Force

暴力枚举所有的子序列,计算它们的和,判断是否能被k整除,时间复杂度为O(2^n)。

def max_subsequence(nums, k):
    n = len(nums)
    res = 0
    for i in range(1, 1 << n):
        s = 0
        for j in range(n):
            if i & (1 << j):
                s += nums[j]
        if s % k == 0:
            res = max(res, bin(i).count('1'))
    return res
DP

利用DP求解最长子序列问题,定义状态dp[i][j]表示前i个元素中最长的和能被j整除的子序列长度。转移方程为:

dp[i][j] = max(dp[i-1][j], dp[i-1][(j-nums[i-1]%k+k)%k]+1)

时间复杂度为O(nk)。

def max_subsequence(nums, k):
    n = len(nums)
    dp = [[0] * k for _ in range(n+1)]
    for i in range(1, n+1):
        for j in range(k):
            dp[i][j] = max(dp[i-1][j], dp[i-1][(j-nums[i-1]%k+k)%k]+1)
    return dp[n][0]
总结

本题可以采用暴力或DP的方法来求解,但是暴力方法时间复杂度太高,不能通过本题。DP方法时间复杂度为O(nk),可以很好地解决问题。