字节跳动青训营|豆包MarsCode AI刷题|二分数字组合

58 阅读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

思路

利用动态规划dp[i][j][k]表示在考虑前i个数字时,第一组的和的个位数为j,第二组的和的个位数为k的划分方案数。不要忘记特殊情况,即计算ab,分别表示总和的个位数是否等于A和B。

dp转移方程的含义

对于每个数字array_a[i-1](注意数组索引从0开始,而这里用i表示当前考虑到的第i个数字,实际上在数组中是array_a[i-1]),有两种选择:

  1. 将该数字加入第一组

    此时,第一组的和的个位数会发生变化,而第二组的和的个位数保持不变。 新的第一组的和的个位数由 j = (x +array_a[i-1] % 10) % 10 计算得到x =((j + 10) - array_a[i-1] % 10) % 10

注意:

  1. array_a[i-1] % 10计算 array_a[i-1] 的个位数
  2. j + 10是为了确保在减去 array_a[i-1] 的个位数后,结果仍然是一个正数
  3. 最后通过再次对 10 取模确保新的个位数在0 到 9 之间
  1. 将该数字加入第二组

    此时第二组的和的个位数会发生变化,而第一组的和的个位数保持不变。 新的第二组的和的个位数可以通过((k + 10) - array_a[i-1] % 10) % 10计算得到

代码

    public static int solution(int n, int A, int B, int[] array_a) {
        int[][][] dp = new int[n+1][15][15];
        dp[0][0][0] = 1;
        int sum = 0;
        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];
 
        }
        int a = sum  % 10 == A? 1:0;
        int b = sum  % 10 == B? 1:0;
        int result = dp[n][A][B] + a + b;
        return result;
    }
 
    public static void main(String[] args) {
        //  You can add more test cases here
        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);
    }
}