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

218 阅读3分钟

问题描述

给定一个数组,请你把数组里的数字分为两组,使一组数字和的个位数等于 A(1 ≤ A ≤ 9),且剩余数字和的个位数等于 B(1 ≤ B ≤ 9);或者一组数字的个数为零,但剩余数字和的个位数等于 A 或 B。请问一共有多少种划分方式?

备注:

  1. 数组里的数字可以相等,但每个数字都是独一无二的。
    比如数组 a 等于[1, 1, 1],A 等于 1,B 等于 2,则一共有三组划分方式:
    第一种:
    A:a[0]
    B:a[1]、a[2]
    第二种:
    A:a[1]
    B:a[0]、a[2]
    第三种:
    A:a[2]
    B:a[0]、a[1]
  2. 可以将所有数字都划分到同一组,使其和的个位数等于 A 或 B;另一组为空
    比如数组 a 等于[1, 1, 1],A 等于 3,B 等于 5,则共有一组划分方式:
    A:a[0]、a[1]、a[2]
    B:空

输入格式

输入第一行包含三个整数 n、A、B(1 ≤ n ≤ 100000,1 ≤ A ≤ 9,1 ≤ B ≤ 9),n 代表需要数组中的数字个数。

第二行,有 n 个元素,代表数组内的数字(1 ≤ 每个数字 ≤ 9)。

输出格式

输出一共有多少种划分方式,结果对 10000007 取余。

样例一

输入:

3 1 2

1 1 1

输出:

3

样例 2

输入:

3 3 5

1 1 1

输出:

1

样例 3

输入:

2 1 1

1 1

输出:

2

问题理解

这道题让我们求组合数,即可以将数字分成两组,也可以把数字全部放到一组,剩下一组不放数字。第一种情况我们并不知道他是哪个数字放哪个组,要我们求组合数,我们可以用动态规划来解决;第二种情况,我们直接把所有数字累加之后取个位数,看它是否等于A或者等于B

数据结构选择

由于数组中的数字范围在1到9之间,我们可以考虑使用动态规划(DP)来解决这个问题。

算法步骤

  1. 初始化:创建一个三维数组dp,初始化dp[0][0][0] = 1,表示没有任何数字时,和为0的情况。
  2. 遍历数组:正常遍历数组,三个for循环,第一个表示第i个数,第二个表示第一组的个位数,第三个表示第二组的个位数。
  3. 结果计算:遍历dp[n][A][B]数组,用递推公式进行计算。
public class Main {
    public static int solution(int n, int A, int B, int[] array_a) {
        //dp: dp[i][j][k] 表示前i个数字,个位数分别为j和k时的划分方案数
        int[][][] dp = new int[n+1][10][10];
        //初始化dp数组
        dp[0][0][0] = 1;
        int sum = 0;
        //第i个数
        for(int i = 1;i <= array_a.length;i++){
            //第一组
            for(int j = 0;j < 10;j++){
                //第二组
                for(int k = 0;k < 10;k++){
                    //加入第一组
                    dp[i][j][k] += dp[i-1][((j + 10) - array_a[i-1] % 10) % 10][k];
                    //加入第二组
                    dp[i][j][k] += dp[i-1][j][((k + 10) - array_a[i-1] % 10) % 10];
                }
            }
            //累加
            sum += array_a[i-1];
 
        }
        //总和个位数是否为A
        int a = sum  % 10 == A? 1:0;
        //总和个位数是否为B
        int b = sum  % 10 == B? 1:0;
        int result = dp[n][A][B] + a + b;
        return result;
    }
 
    public static void main(String[] args) {
        int[] array1 = {1, 1, 1};
        int[] array2 = {1, 1, 1};
        int[] array3 = {1, 1};
 
        System.out.println(solution(3, 1, 2, array1) == 3);
        System.out.println(solution(3, 3, 5, array2) == 1);
        System.out.println(solution(2, 1, 1, array3) == 2);
    }
}

豆包ai给了我解题思路,让我更好的运用DP算法,递推公式。