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

    题目

    传送门:QWQ

    分析

    蒟蒻不会数位dp,又是现学的

    用$ dp[i][j][k] $ 表示表示长度为i开头j的所有数字中k的个数

    然后预处理出这个数组,再计算答案

    代码

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    ll dp[25][15][15], ans[15], b[25], sum[25];
    int solve(ll x,ll d){
        int len=0; ll bef=x;
        for(;x;x/=10){ b[++len]=x%10; }
        for(int i=1;i<len;i++)
        for(int j=1;j<10;j++){
            for(int k=0;k<10;k++) ans[k]+=dp[i][j][k]*d;
        }
        for(int i=len;i>0;i--){
            for(int j=0;j<b[i];j++){
                if(!j&&len==i) continue;// 最高位不是0打头 
                for(int k=0;k<10;k++) ans[k]+=dp[i][j][k]*d;
            }
            ans[b[i]]+=d*(bef%sum[i]+1);
        }
    }
    int main(){
        ll aa,bb; scanf("%lld%lld",&aa,&bb);
        sum[1]=1;
        for(int i=2;i<13;i++) sum[i]=sum[i-1]*10;
        for(int i=0;i<10;i++) dp[1][i][i]=1;
        
        for(int i=2;i<13;i++)
        for(int j=0;j<10;j++)
        for(int k=0;k<10;k++){
            for(int l=0;l<10;l++){
                dp[i][j][l]+=dp[i-1][k][l];
            }
            dp[i][k][k]+=sum[i-1];//以k为开头的数 
        }
        solve(bb,1); solve(aa-1,-1);
        for(int i=0;i<9;i++) printf("%lld ",ans[i]);
        printf("%lld
    ",ans[9]);
        return 0;
    }
  • 相关阅读:
    计算机故障
    线程池&进程池
    机箱-网卡-声卡-显卡-显示器
    scrapy请求传参-BOSS反爬
    计算机硬件-主板
    计算机硬件-内存
    计算机硬件-硬盘
    计算机硬件-CPU
    ZJNU 1223
    ZJNU 1217
  • 原文地址:https://www.cnblogs.com/noblex/p/9192927.html
Copyright © 2011-2022 走看看