AI刷题题解二分数字组合 | 豆包MarsCode AI刷题

81 阅读3分钟
今天看到有人问了这个二分数字组合,正好解答一下。

题目链接:二分数字组合 - MarsCode

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


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

通过题目我们可以得知,我们可以将一个数组拆分成两个,并且两个数组和的个位数等于题目要求 其中,拆分的两个数组一个可以为空。

   我们将题目可以分成两个要求
   1.两个数组满足两个目标
   2.一个数组为空,其余和的个位数为目标之一
   
   
   我们先考虑第二个要求
   在这里第二个要求的解决方案是,先将题目数组对10求余数
   这一步先保证数组里保存的是个位数,这便于之后的运算
   接下来我们使用sum函数将数组个位数求一下和,并二次对10求余
   然后我们可以得出,是否满足于条件2
   同时,因为条件2只需要数组的全部,只有一种特殊情况
   判断完成后返回就可以了
   
   
    array_a = [x % 10 for x in array_a]
    total_sum = sum(array_a)
    total_sum %= 10
    if (total_sum == A or total_sum == B):
        return 1
    if (total_sum != (A + B) % 10):
        return 0
然后我们看第一个要求,将数组拆分,而且相同的数字也算+1的结果
首先想到动态规划

 f = [[0 for _ in range(10)] for _ in range(n + 1)]
初始一个二维数组 
包含 `n+1` 行和 `10` 列,并且所有元素都被初始化为 `0`

然后我们遍历数组,从1开始直到n
这一步是遍历每一个元素
然后我们继续遍历,从09
这一步是确认个位数的和
for i in range(1, n + 1):
        for j in range(10):
# 当前元素不放入当前和的方案数,等于前一个元素的方案数
            f[i][j] += f[i - 1][j]
# 当前元素放入当前和的方案数,等于前一个元素减去当前元素个位数后的方案数
            f[i][j] += f[i - 1][(j - array_a[i - 1] + 10) % 10]
上述两步我们动态进行一个状态的改变
表示在考虑前 `i` 个元素时,和的个位数为 `j` 的方案数,等于不考虑第 `i` 个元素时,和的个位数为 `j` 的方案数。
这是因为如果不选择第 `i` 个元素,那么前 `i-1` 个元素的和的个位数仍然是 `j`,所以方案数不变。
表示在考虑前 `i` 个元素时,和的个位数为 `j` 的方案数,等于不考虑第 `i` 个元素时,和的个位数为 `j - array_a[i - 1]` 的方案数。
这是因为如果选择第 `i` 个元素,那么前 `i-1` 个元素的和的个位数需要减去第 `i` 个元素的个位数,即 `array_a[i - 1]`,才能得到当前和的个位数 `j`。
由于个位数的范围是 `0` 到 `9`,所以需要对结果进行模 `10` 运算,以确保结果在正确的范围内。



最后,我们返回二维数组的[n][B]

20231030_152430.jpg