zoukankan      html  css  js  c++  java
  • [HAOI2010]计数

    数位DP逐位确定的思想

    因为我们要求小于当前数的个数,位数不即它的,可以认为有前导零

    所以可以枚举每一位(给定数的位数),再枚举当前位填什么,

    当填的数小于给定数的这一位时,后面可以直接用组合数,因为填什么,怎么填都符合要求(小于给定数),就是剩下的数集中还没有被填的数都要做组合数(这个求法很妙???)

    当填的数等于给定数的这一位时,此时值为一,不能计算,要推下去(就是下面再小于等于都是基于这一位等于来的)

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<queue>
     7 #include<set>
     8 #include<map>
     9 #include<vector>
    10 #include<stack>
    11 using namespace std;
    12 typedef long long ll;
    13 const int maxn=57;
    14 ll ans,n;
    15 ll a[maxn],cnt[maxn],C[maxn][maxn];
    16 char s[maxn];
    17 ll get(int n){
    18   ll ret=1;
    19   for(int i=0;i<=9;i++){
    20     if(cnt[i]){
    21       ret*=C[n][cnt[i]];
    22       n-=cnt[i];
    23     }
    24   }
    25   return ret;
    26 }
    27 int main(){
    28   scanf("%s",s+1);n=strlen(s+1);
    29   for(int i=1;i<=n;i++){
    30     a[i]=s[i]-'0';cnt[a[i]]++;
    31   }
    32   C[0][0]=1;
    33   for(int i=0;i<=51;i++){
    34     for(int j=0;j<=51;j++){
    35       C[i+1][j]+=C[i][j];C[i+1][j+1]+=C[i][j];
    36     }
    37   }
    38   for(int i=1;i<=n;i++){
    39     for(int j=0;j<a[i];j++){
    40       if(cnt[j]){
    41         cnt[j]--;ans+=get(n-i);cnt[j]++;
    42       }
    43     }
    44     cnt[a[i]]--;
    45   }
    46   cout<<ans<<endl;
    47 }
  • 相关阅读:
    nginx的简介和配置文件实例(一)
    Tomcat基础配置(一)
    redis主从复制以及SSDB主主复制环境部署记录(四)
    redis主从原理介绍(三)
    redis介绍和安装和主从介绍(二)
    celery
    网络-sdn
    djang问题汇总
    django路由url
    django开发环境配置
  • 原文地址:https://www.cnblogs.com/lcan/p/9927317.html
Copyright © 2011-2022 走看看