周赛298——个位数字为 K 的整数之和

142 阅读1分钟

原题:2310. 个位数字为 K 的整数之和 - 力扣(LeetCode)

解题的思路类似于:322. 零钱兑换 - 力扣(LeetCode)

考虑用动态规划来解,对于本题。当考虑M在个位等于k的情况下的最少集合数,可以通过枚举所有小于等于M且个位为k的数。分别为:k, 10 + k,20 + k, 30 + k,40 + k....

其次,我们可以先检查下能否用个位等于k来组合出M,具体的思路我这里比较笨拙,就是把1到10乘一遍然后计算个位看有没有出现。如下:

private boolean check(int num, int k) {
    int right = num % 10;
    for (int i = 1; i <= 10; i++) {
        if ((i * k) % 10 == right && (i * k) <= num) {
            return true;
        }
    }
    return false;
}

完整代码:

   public int minimumNumbers(int num, int k) {
        if (num == 0) {
            return 0;
        }
        if (num % 10 == k) {
            return 1;
        }
        int[][] mem = new int[num + 1][10];
        for (int i = 0; i < num + 1; i++) {
            for (int j = 0; j < 10; j++) {
                if (!check(i, j)) {
                    mem[i][j] = -1;
                    continue;
                }
                if (i % 10 == j) {
                    mem[i][j] = 1;
                    continue;
                }
                if (i < j) {
                    mem[i][j] = -1;
                    continue;
                }
                mem[i][j] = Integer.MAX_VALUE;
                for (int l = j; l < i; l += 10) {
                    //System.out.println(i + " " + j + " " + l);
                    if (mem[i - l][j] != -1) {
                        mem[i][j] = Math.min(mem[i][j], 1 + mem[i - l][j]);
                    }
                }
            }
        }
        return mem[num][k];
    }

    // 这种写法num = 10,k = 8 的时候判断不出来
//    private boolean check(int num, int k) {
//        int right = num % 10;
//        for (int i = 0; i < 10; i++) {
//            if ((i * k) % 10 == right) {
//                return true;
//            }
//        }
//        return false;
//    }

    private boolean check(int num, int k) {
        int right = num % 10;
        for (int i = 1; i <= 10; i++) {
            if ((i * k) % 10 == right && (i * k) <= num) {
                return true;
            }
        }
        return false;
    }