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

    题目描述

    你有一组非零数字(不一定唯一),你可以在其中插入任意个0,这样就可以产生无限个数。比如说给定{1,2},那么可以生成数字12,21,102,120,201,210,1002,1020,等等。

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

    输入输出格式

    输入格式:

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

    输出格式:

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

    输入输出样例

    输入样例#1

    1020

    输出样例#1

    7

    说明

    n的长度不超过50,答案不超过2^63-1.

    题解

    类似于数位dp

    求比这个排列小的排列个数

    但是元素有重复

    可重复元素的排列个数是 : 排列的长度的阶乘 / 所有元素出现次数的阶乘之积

    所以我们可以考虑一个比较暴力的方法 :

    枚举每一位放什么

    就类似于数位dp

    如果这一位是x

    那么放0~x-1且在原排列中存在的数就是不卡上界的

    后面的可以随便放

    如果放x,那么就是卡上界的

    就需要继续枚举下一位来处理情况

    然后本题在计算过程中会爆longlong

    注意处理

    代码

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    # define LL long long
    const int M = 55 ;
    const int N = 13 ;
    using namespace std ;
    int n ;
    char s[M] ;
    int t[N] ;
    LL Ans , fac[M] ;
    inline LL Solve(int n) {
    	LL ret = 1LL ;
    	bool vis[N] ;
    	memset(vis , false , sizeof(vis)) ;
    	for(int i = 1 ; i <= n ; i ++) {
    	    ret *= i ;
    	    for(int i = 0 ; i <= 9 ; i ++)
    	        if(!vis[i] && ret % fac[t[i]] == 0)
    	            ret /= fac[t[i]] , vis[i] = true ;
    	}
    	return ret ;
    }
    int main() {
    	scanf("%s",s + 1) ; n = strlen(s + 1) ;
    	for(int i = 1 , x ; i <= n ; i ++) {
    		x = s[i] - '0' ;
    		++ t[x] ;
    	}
    	fac[0] = 1 ;
    	for(int i = 1 ; i <= 18 ; i ++) fac[i] = fac[i - 1] * i ;
    	for(int i = 1 , x ; i <= n ; i ++) {
    		x = s[i] - '0' ;
    		for(int j = 0 ; j < x ; j ++) { 
    			if(!t[j]) continue ;
    			--t[j] ; // 这一位选择不卡上界的j 
    			Ans += Solve(n - i) ;
    			++t[j] ; 
    		}
    		--t[x] ; // 这一位选择卡上界的x,因为如果到了这一位说明上一位也卡上界了,那么就去枚举下一位是什么 
    	}
    	printf("%lld
    ",Ans) ;
    	return 0 ;
    }
    
  • 相关阅读:
    phpcms调用指定文章内容模型的ID
    phpcms V9的各种功能总结
    如何使用ajax与php实现简单的流程管理
    键盘按键和键盘对应代码表
    ajax实现省、市、区、三级联动(例题)
    用ajax做登录与删除
    var_dump、echo、print_r 的区别
    字符串删除重复字符
    树的非递归遍历
    字符串操作_(不使用库函数)
  • 原文地址:https://www.cnblogs.com/beretty/p/9885982.html
Copyright © 2011-2022 走看看