打卡第二天 | 豆包MarsCode AI刷题

116 阅读3分钟

二分数字组合

问题描述

小F面临一个有趣的挑战:给定一个数组,她需要将数组中的数字分为两组。分组的目标是使得一组数字的和的个位数等于给定的 A,另一组数字的和的个位数等于给定的 B。除此之外,还有一种特殊情况允许其中一组为空,但剩余数字和的个位数必须等于 A 或 B。小F需要计算所有可能的划分方式。

例如,对于数组 [1, 1, 1] 和目标 A = 1,B = 2,可行的划分包括三种:每个 1 单独作为一组,其余两个 1 形成另一组。如果 A = 3,B = 5,当所有数字加和的个位数为 3 或 5 时,可以有一组为非空,另一组为空。


测试样例

样例1:

输入:n = 3,A = 1,B = 2,array_a = [1, 1, 1]
输出:3

样例2:

输入:n = 3,A = 3,B = 5,array_a = [1, 1, 1]
输出:1

样例3:

输入:n = 2,A = 1,B = 1,array_a = [1, 1]
输出:2

样例4:

输入:n = 5,A = 3,B = 7,array_a = [2, 3, 5, 7, 9]
输出:0

解题思路

  1. 计算数组和:首先计算数组所有元素的和 total_sum,并获取其个位数 total_sum % 10

  2. 动态规划表:使用一个二维 DP 表 dp[i][j] 来表示前 i 个数字能否分配成和个位数为 j 的集合。这里的 j 取值范围是 0 到 9。

  3. 状态转移

    • 对于每个数字 array[i],我们可以选择将其放入某一组,或者不放入。我们更新 DP 表以反映当前选择的影响。

    • 对于 j 从 0 到 9,我们有两种选择:

      • 不选择当前数字,保持之前的状态 dp[i-1][j]
      • 选择当前数字,更新状态为 (j + array[i]) % 10
  4. 考虑特殊情况:如果允许其中一组为空,我们需要判断 total_sum % 10 是否与 A 或 B 相等。

  5. 结果计算:最后,我们需要统计所有符合条件的划分方式。

动态规划的基本思想 动态规划(Dynamic Programming,DP)算法通常用于求解某种具有最优性质的问题。在这类问题中,可能会有许多可行解,每一个解都对应一个值,我们希望找到具有最优值的解。 动态规划算法与分治法类似,其基本思想也是将待求解的问题分解成若干个子问题,先求解子问题,然后从这些子问题的解中 得到原有问题的解。与分治法不同的是,动态规划经分解后得到的子问题往往 不是相互独立 的。

(分治算法也可以解决分解后得到的子问题不是相互独立的情况,只是要对公共子问题进行单独求解。这样会使分治法求解问题的复杂度大大提高。对此类问题如果感兴趣的话可以看我的另外一篇文章——分治法详细讲解。)

动态规划分为两种:选择 or 加和 注意边界,想明白dp代表的意义

解决代码

def solution(n, A, B, array_a):
    total_sum = sum(array_a)
    
    # 动态规划数组,dp[i][j]表示前i个数字组成的和的个位数为j的方式数量
    dp = [[0] * 10 for _ in range(n + 1)]
    dp[1][array_a[0]%10] = 1
    # DP 填充
    for i in range(1, n + 1):
        num = array_a[i - 1]
        for j in range(10):
            # 不选择当前数字
            dp[i][j] += dp[i - 1][j]
            dp[i][(j + num) % 10] += dp[i - 1][j]


    # 统计符合条件的方式
    count = 0
    
    # 两组都非空
    count += (dp[n][A]+dp[n][B])
    # print(dp)

    # 允许一组为空的情况
    total_digit = total_sum % 10
    if total_digit != (A+B)%10:
        count = 0
    if total_digit == A or total_digit ==B:
        count += 1;

    return count



if __name__ == "__main__":
    #  You can add more test cases here
    print(solution(3, 1, 2, [1,1,1]) == 3 )
    print(solution(3, 3, 5, [1,1,1]) == 1 )
    print(solution(2, 1, 1, [1,1]) == 2 )