• 【BZOJ1833】[ZJOI2010] count 数字计数(数位DP)


    点此看题面

    大致题意: 求在给定的两个正整数(a)(b)中的所有整数中,(0sim9)各出现了多少次。

    数位(DP)

    很显然,这是一道数位(DP)题。

    我们可以用前缀和的思想,分别求出小于等于(b)时的答案和小于等于(a-1)时的答案,然后将两个答案相减,就可以得出(asim b)之间的答案了。

    对于每一位,若设(x)为当前需要小于的数字(即(b)(a-1))当前可以填的数字有两种情况

    ①前面的数字已经保证当前数字小于(x)。则这位数字可以在(0sim9)任意填

    ②前面的数字全部与(x)相同位上的数字一样。则这位上填的数字必须小于等于(x)这一位上的数字。

    还有一个特别要注意的是,对于数字前多出的前导0要单独特判处理

    代码

    #include<bits/stdc++.h>
    #define LL long long
    #define N 12
    using namespace std;
    LL a,b,num[N+5],s[N+5],f[N+5],ans[10][2];//两个ans数组,一个存储小于等于b时的答案,一个存储小于等于a-1时的答案
    inline char tc()
    {
        static char ff[100000],*A=ff,*B=ff;
        return A==B&&(B=(A=ff)+fread(ff,1,100000,stdin),A==B)?EOF:*A++;
    }
    inline void read(LL &x)
    {
        x=0;LL f=1;char ch;
        while(!isdigit(ch=tc())) f=ch^'-'?1:-1;
        while(x=(x<<3)+(x<<1)+ch-'0',isdigit(ch=tc()));
        x*=f;
    }
    inline void write(LL x)
    {
        if(x<0) putchar('-'),x=-x;
        if(x>9) write(x/10);
        putchar(x%10+'0');
    }
    inline void dp(LL x,int pos)//数位DP的具体过程
    {
    	register int i,j;LL tot=0,w=x,t;
    	while(w) num[++tot]=w%10,w/=10;//将x十进制下的每一位分解
    	for(i=tot;i>0;--i)
    	{
    		for(j=0;j<10;ans[j++][pos]+=f[i-1]*num[i]);//第1种情况,该位可以任意填
    		for(j=0;j<num[i];ans[j++][pos]+=s[i-1]);//第2种情况,这里先处理该位小于x上这位的情况
    		for(j=i-1,t=0;j>0;--j) (t*=10)+=num[j];//计算出这位填等于x上这位的情况数
    		ans[num[i]][pos]+=t+1,ans[0][pos]-=s[i-1];//单独处理该位等于x上这位的情况数,并将ans[0]减去有多余前导0的情况数
    	}
    }
    int main()
    {
    	register int i;
    	read(a),read(b);
    	for(i=s[0]=1;i<N+5;++i)//预处理
    		f[i]=f[i-1]*10+s[i-1],s[i]=s[i-1]*10;
    	for(dp(b,0),dp(a-1,1),i=0;i<10;++i)//分别计算出小于等于b和小于等于a-1时的答案
    		write(ans[i][0]-ans[i][1]),putchar(' ');//将两个答案相减
        return 0;
    }
    
  • 相关阅读:
    PHP实现多进程并行操作(可做守护进程)
    检测php文件是否有bom头
    安全过滤函数
    模式修正符
    php中const与define的使用区别
    常要用正则表达式
    htaccess 伪静态的规则
    把返回的数据集转换成数组树
    ExtJS实战(3)spring
    ExtJS实战(4)struts
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/BZOJ1833.html
Copyright © 2020-2023  润新知