zoukankan      html  css  js  c++  java
  • 动态规划-数位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];
        }
    

      

  • 相关阅读:
    C# 获取计算机相关信息
    C# 创建Windows服务demo
    C# 嵌入互操作类型
    使用开源框架Sqlsugar结合mysql开发一个小demo
    C# 实现最小化托盘功能
    面试-PA和XSYX面试小结
    0103-springmvc的基本流程
    0102-aop
    java并发编程-12个原子类
    ej3-0开端
  • 原文地址:https://www.cnblogs.com/hyserendipity/p/12903933.html
Copyright © 2011-2022 走看看