动态规划-数位dp-1012. 至少有 1 位重复的数字

时间:2020-05-17
本文章向大家介绍动态规划-数位dp-1012. 至少有 1 位重复的数字,主要包括动态规划-数位dp-1012. 至少有 1 位重复的数字使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

2020-05-17 09:03:13

问题描述:

给定正整数 N,返回小于等于 N 且具有至少 1 位重复数字的正整数的个数。 

示例 1:

输入:20
输出:1
解释:具有至少 1 位重复数字的正数(<= 20)只有 11 。
示例 2:

输入:100
输出:10
解释:具有至少 1 位重复数字的正数(<= 100)有 11,22,33,44,55,66,77,88,99 和 100 。
示例 3:

输入:1000

输出:262
提示:

1 <= N <= 10^9

问题求解:

经典的数位dp题,需要注意的是leading zero不能算为使用过的数字即可。

    int[] digits = new int[64];
    // pos,limit, used,f,lead
    int[][][][][] dp = new int[12][2][1 << 10][2][2];
    
    public int numDupDigitsAtMostN(int N) {
        int pos = 0;
        while (N > 0) {
            digits[pos++] = N % 10;
            N /= 10;
        }
        
        //for (int i = pos - 1; i >= 0; i--) System.out.println(digits[i]);
        
        for (int i = 0; i < 12; i++) {
            for (int j = 0; j < 2; j++) {
                for (int k = 0; k < 1 << 10; k++) {
                    for (int t = 0; t < 2; t++) {
                        Arrays.fill(dp[i][j][k][t], -1);
                    }
                }
            }
        }
        
        return dfs(pos - 1, 1, 0, 0, 1);
    }
    
    private int dfs(int pos, int limit, int used, int f, int lead) {
        if (pos == -1) return f == 1 ? 1 : 0;
        if (dp[pos][limit][used][f][lead] != -1) return dp[pos][limit][used][f][lead];
        dp[pos][limit][used][f][lead] = 0;
        int up = limit == 1 ? digits[pos] : 9;
        for (int i = 0; i <= up; i++) {
            int ns = used;
            if (!(lead == 1 && i == 0)) ns = ns | (1 << i);
            int flag = 0;
            if (((1 << i) & used) != 0) {
                if (i == 0 && lead == 1) flag = 0;
                else flag = 1;
            }
            dp[pos][limit][used][f][lead] += dfs(pos - 1, limit == 1 && i == up ? 1 : 0, ns, f == 1 || flag == 1 ? 1 : 0, lead == 1 && i == 0 ? 1 : 0);
        }
        return dp[pos][limit][used][f][lead];
    }

  

原文地址:https://www.cnblogs.com/hyserendipity/p/12903933.html