• LeetCode至 少有 1 位重复的数字


     

    给定正整数 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

    数位dp可以解决,不知道怎么写。
    考虑一种通解的方法:原答案即N-没有重复的数字。关键是求没有重复的数字
    对于位数比N小的情况,我们可以直接排列组合求。
    对于与N相同的情况,我们从最高位根据数字的限制(limit)依此排列求解
    int C(int m,int n)
        {
            int res=1;
            while(n)
            {
                res*=m;
                m--;
                n--;
            }           
            return res;
        }
        int numDupDigitsAtMostN(int N) {
            vector<int>a;
            
            for(int x=N+1;x!=0;x/=10)
                a.push_back(x%10);
            int n=a.size();
            reverse(a.begin(),a.end());
            int res=0;
            for(int i=1;i<n;i++)
                res+=9*C(9,i-1);
            cout<<res<<endl;
            map<int,int>contain;
            for(int i=0;i<n;i++)
            {
                for(int j=i>0?0:1;j<a[i];j++)
                {
                    if(contain[j]==0)
                        res+=C(9-i,n-i-1);
                }
                if(contain[a[i]]>0)
                    break;
                contain[a[i]]++;
                
            }
            return N-res;
        }

    数位dp

    int dfs(int t, bool up, bool ze, bool rp, int mask) {
            if (t < 0) return rp;
            if (!up && ~dp[t][ze][rp][mask]) return dp[t][ze][rp][mask];
            int ret = 0, I = up ? a[t] : 9;
            rep(i, 0, I + 1) {
                bool nrp = rp;
                int nmas = mask;
                if (!(ze & i == 0)) {
                    nrp |= mask >> i & 1;
                    nmas |= 1 << i;
                }
                ret += dfs(t - 1, up & (i == I), ze & (i == 0),
                    nrp, nmas);
            }
            if (!up) dp[t][ze][rp][mask] = ret;
            return ret;
        }
    
        int numDupDigitsAtMostN(int N) {
            memset(dp, -1, sizeof(dp));
            int n = 0;
            while (N > 0) {
                a[n++] = N % 10;
                N /= 10;
            }
            return dfs(n - 1, 1, 1, 0, 0);        
        }



  • 相关阅读:
    hdu find the most comfortable road(贪心+并查集)
    hdu 迷瘴(贪心)
    Excel中指定的sheet名称或索引读取数据到DataTable
    SQLServer 批量插入数据的两种方法
    javascript基础教程3
    Enterprise Library 4.1学习笔记 配置应用程序块(c/s和b/s均适用)
    关于同一用户不能同时在两台电脑上登录问题的解决方案
    获取当天为一年中的第几周
    javascript基础教程4
    Excel导出方法选择(转自gwf25sz)
  • 原文地址:https://www.cnblogs.com/flightless/p/10546969.html
Copyright © 2020-2023  润新知