zoukankan      html  css  js  c++  java
  • bzoj 1833: [ZJOI2010]count 数字计数【数位dp】

    非典型数位dp
    先预处理出f[i][j][k]表示从后往前第i位为j时k的个数,然后把答案转换为ans(r)-ans(l-1),用预处理出的f数组dp出f即可(可能也不是dp吧……)

    #include<iostream>
    #include<cstdio>
    using namespace std;
    long long l,r,t[25];
    struct dp
    {
        long long a[15];
        dp operator + (dp x)
        {
            dp r;
            for(int i=0;i<=9;i++)
    			r.a[i]=a[i]+x.a[i];
            return r;
        }
    }f[20][20];
    dp work(long long x)
    {
        dp ans;
     	for(int i=0;i<=9;i++)
    		ans.a[i]=0;
        if(!x)
        {
            ans.a[0]=1;
            return ans;
        }
        int len=15;
        while(t[len]>x)
    		len--;
        for(int i=1;i<len;i++)
    		for(int j=1;j<=9;j++)
    			ans=ans+f[i][j];
        ans.a[0]++;
        int cur=x/t[len];
        for(int i=1;i<cur;i++)
    		ans=ans+f[len][i];
        x%=t[len];
        ans.a[cur]+=x+1;
     	for(int i=len-1;i;i--)
        {
            cur=x/t[i];
            for(int j=0;j<cur;j++)
    			ans=ans+f[i][j];
            x%=t[i];
            ans.a[cur]+=x+1;
        }
        return ans;
    }
    int main()
    {
        t[1]=1;
        for(int i=2;i<=15;i++)
    		t[i]=t[i-1]*10;
        for(int i=0;i<=9;i++)
    		f[1][i].a[i]=1;
        for(int i=2;i<=12;i++)
    		for(int j=0;j<=9;j++)
    			for(int k=0;k<=9;k++)
    			{
    				f[i][k]=f[i][k]+f[i-1][j];
    				f[i][k].a[k]+=t[i-1];
    			}
        scanf("%lld%lld",&l,&r);
        dp ans1=work(r),ans2=work(l-1);//cout<<"aa";
        for(int i=0;i<=9;i++)
    		printf("%lld ",ans1.a[i]-ans2.a[i]);
        return 0;
    }
    
  • 相关阅读:
    [EOJ]2019 ECNU XCPC March Selection #1
    [模板]宏定义
    [POJ]poj1961,poj2406(KMP)
    [模板]KMP
    [CF]Avito Cool Challenge 2018
    [CF]Codeforces Round #528 Div.2
    [POJ]POJ1328(贪心)
    洛谷 P3808 【模板】AC自动机(简单版) 题解
    中科院的难题 题解
    【转】洛谷 P3722 [AH2017/HNOI2017]影魔 题解
  • 原文地址:https://www.cnblogs.com/lokiii/p/9374863.html
Copyright © 2011-2022 走看看