zoukankan      html  css  js  c++  java
  • [ZJOI2010]数字计数 题解

    题面

    这道题是一道数位DP的模板题;

    因为窝太蒟蒻了,所以不会递推,只会记忆化搜索;

    首先,咋暴力咋来;

    将一个数分解成一个数组,这样以后方便调用;

    数位DP的技巧:(用1~b的答案)-(1~a的答案)就是(a~b的答案);

    那么对于每个数码i,我们做两次dfs(分别以a为上界和以b为上界);

    设正在搜索的数码是digit:

    枚举每一位,当这位==digit时,便将答案+1,并记忆化;

    然后就没了;

    可是这样做忽略了两个重要的事情:

    1.可能存在前导零;

    2.目前搜到的数比目标值要大;

    对于这两件事,在dfs中记录limit=1表示改为的上界就是目标的这一位的上界,否则对这一位不作要求;

    head=1表示目前搜到的数不存在前导零;

    很显然的:(伪代码)

    long long dfs(int pos,int limit,int lead,int digit,long long sum)
    
    register int up=9; //up表示这一位的上界

    if(limit) up=num[pos]; inc(j,0,up) ans+=dfs(pos-1,(j==up)&&limit,lead||j,digit,sum+((j||lead)&&(j==digit)));

    利用好位运算,然后注意要记忆化,然后就可以AC了;

    #include <bits/stdc++.h>
    #define inc(i,a,b) for(register int i=a;i<=b;i++)
    using namespace std;
    long long a,b,f[34][3400],num[34];
    long long  dfs(int pos,int limit,int lead,int digit,long long sum)
    {
        long long ans=0;
        if(pos<=0) return sum;      	
        if(!limit&&lead&&f[pos][sum]!=-1) return f[pos][sum];
        register int up=9; if(limit) up=num[pos];  
        inc(j,0,up) ans+=dfs(pos-1,(j==up)&&limit,lead||j,digit,sum+((j||lead)&&(j==digit)));  	
        if(!limit&&lead) f[pos][sum]=ans;
        return ans;
    }
    long long work(long long x,register int type)
    {
        memset(f,-1,sizeof(f));
        register int len=0;
        while(x){
            num[++len]=x%10;
            x/=10;
        }
        return dfs(len,1,0,type,0);
    }
    int main()
    {
        cin>>a>>b;
        for(register int i=0;i<=9;i++){
            cout<<work(b,i)-work(a-1,i);
            if(i!=9) cout<<" ";
        }
    }
    /*
    1 99
    */
    
  • 相关阅读:
    JavaWeb
    JavaWeb
    appium+python实现手机计算器随机计算
    使用uiautomatorviewer工具遇到以下问题-Unexpected error while obtaining UI hierarchy
    appium+python启动手机淘宝
    appium基本环境搭建
    python多个字典“合并”成一个字典
    HTML基础1-图像
    HTML基础1-文本
    RobotFrame简要安装
  • 原文地址:https://www.cnblogs.com/kamimxr/p/11794726.html
Copyright © 2011-2022 走看看