• BZOJ2425: [HAOI2010]计数


    BZOJ2425: [HAOI2010]计数

    Description

    你有一组非零数字(不一定唯一),你可以在其中插入任意个0,这样就可以产生无限个数。

    比如说给定{1,2},那么可以生成数字12,21,102,120,201,210,1002,1020,等等。

    现在给定一个数,问在这个数之前有多少个数。(注意这个数不会有前导0).

    Input

    只有1行,为1个整数n.

    Output

    只有整数,表示N之前出现的数的个数。

    Sample Input

    1020

    Sample Output

    7

    HINT

    n的长度不超过50,答案不超过263-1.


    题解Here!

    这题思路和数位$DP$差不多。

    一位一位向前推进。

    首先我们知道,对于一个数,把其中的$0$删掉,相当于把$0$放到了前面。

    所以这个问题就是让我们求一下给我们的数字的全排列中比当前小的有几个。

    设$num[i]$代表数字$i(iin[0,9])$有几个。

    那么全排列就是这个式子:
    $$frac{(sum_{i=0}^9num[i])!}{prod_{i=0}^9num[i]!}$$

    当然如果$num[i]==0$那么不参与运算。。。

    但是这样的话$long long$表示存不下。

    我已经说了我不会再写高精度的!

    所以继续想优化。

    假设现在有$m$个位置。

    我们先把$0$放法放好:
    $$C_m^{num[0]}$$

    之后就只有$m-num[0]$个位置。

    然后再放$1$:
    $$C_{m-num[0]}^{num[1]}$$

    以此类推。。。

    所以答案长这个样:
    $$Ans=C_m^{num[0]} imes C_{m-num[0]}^{num[1]} imes... imes C_{m-num[0]-num[1]-...-num[8]}^{num[9]}$$

    然后这个组合数就用杨辉三角什么的乱搞就好了。

    附代码:

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #define MAXN 1010
    using namespace std;
    int n,val[MAXN],num[MAXN];
    long long triangle[MAXN][MAXN];
    inline void read(){
    	char c=0;
    	n=0;
    	while(c<'0'||c>'9')c=getchar();
    	while(c>='0'&&c<='9'){val[++n]=c-'0';num[val[n]]++;c=getchar();}
    }
    long long C(long long n,long long m){
    	if(triangle[n][m])return triangle[n][m];
    	if(m==1)return n;
    	if(m==0||m==n)return 1;
    	if(m>n)return 0;
    	triangle[n][m]=C(n-1,m)+C(n-1,m-1);
    	return triangle[n][m];
    }
    long long solve(int x){
        long long s=1;
        for(int i=0;i<=9;i++)
        if(num[i]){
            s*=C(x,num[i]);
            x-=num[i];
        }
        return s;
    }
    void work(){
    	long long ans=0;
    	for(int i=1;i<=n;i++){
    	    for(int j=0;j<val[i];j++)
            if(num[j]){
                num[j]--;
                ans+=solve(n-i);
                num[j]++;
            }
            num[val[i]]--;
        }
        printf("%lld
    ",ans);
    }
    int main(){
    	read();
    	work();
        return 0;
    }
    
  • 相关阅读:
    MAUI 通用权限框架(ABP)
    MAUI 入门教程系列(3.多目标平台)
    MAUI 入门教程系列(4.通用主机)
    Swagger 入门教程
    js对比两个文本的差异并高亮显示差异部分
    崩坏3模拟抽卡243亿张补给卡对比精准和扩充池
    银行业务概要相关知识总结
    R720 idRAC 会话数RAC0218:已达到用户会话的最大数,重起idRAC yi
    linux nginx 安装
    异构系统集成架构与流程图
  • 原文地址:https://www.cnblogs.com/Yangrui-Blog/p/9492835.html
Copyright © 2020-2023  润新知