题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2425

题意:

  给你一个数字n,长度不超过50。

  你可以将这个数字:

    (1)去掉若干个0

    (2)打乱后重新排列

  问你可以产生多少个小于n的数字。

题解:

  题目中的第一个操作其实是没有用的。

  去掉若干个0之后再重新排列(不允许前导0),和不去0直接重新排列(允许前导0),其实是等价的。

  所以按照数位dp的方法从高到低按位统计。

  如n = 2345时,分别统计前缀为0~1, 20~22, 230~233, 2340~2344的答案。

  最高位为第1位。

  假设当前考虑到第i位,1~i-1位都和原数字n完全匹配。

  枚举第i位可以填了x∈[0,a[i]),则先让cnt[x]--。

  然后就是i+1位之后的数如何填了。

  设len = n-i。

  方案数 = 先从len个位置中找了cnt[0]个位置全填0的方案数 * 又从(len-cnt[0])个位置中找了cnt[1]个位置全填1的方案数...

  方案数 = C(len,cnt[0]) * C(len-cnt[0],cnt[1]) * C(len-cnt[0]-cnt[1],cnt[2])...

  最后再让cnt[x]++回来,然后cnt[a[i]]--就好了。

AC Code:

 #include <iostream>
#include <stdio.h>
#include <string.h>
#define MAX_N 55
#define MAX_D 15 using namespace std; int n;
long long ans=;
long long a[MAX_N];
long long cnt[MAX_N];
long long c[MAX_N][MAX_N];
char s[MAX_N]; void read()
{
scanf("%s",s+);
n=strlen(s+);
for(int i=;i<=n;i++) cnt[a[i]=s[i]-'']++;
} void cal_c()
{
c[][]=;
for(int i=;i<=n;i++)
{
c[i][]=;
for(int j=;j<=i;j++)
{
c[i][j]=c[i-][j]+c[i-][j-];
}
}
} long long cal_p(int len)
{
long long now=;
for(int i=;i<=;i++)
{
now*=c[len][cnt[i]];
len-=cnt[i];
}
return now;
} void cal_ans()
{
for(int i=;i<=n;i++)
{
for(int j=;j<a[i];j++)
{
cnt[j]--;
ans+=cal_p(n-i);
cnt[j]++;
}
cnt[a[i]]--;
}
} void work()
{
cal_c();
cal_ans();
printf("%lld\n",ans);
} int main()
{
read();
work();
}

BZOJ 2425 [HAOI2010]计数:数位dp + 组合数的更多相关文章

  1. [HAOI2010]计数 数位DP+组合数

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

  2. bzoj 2425 [HAOI2010]计数 dp+组合计数

    [HAOI2010]计数 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 451  Solved: 289[Submit][Status][Discus ...

  3. BZOJ 1833 数字计数 数位DP

    题目链接 做的第一道数位DP题,听说是最基础的模板题,但还是花了好长时间才写出来..... 想深入了解下数位DP的请点这里 先设dp数组dp[i][j][k]表示数位是i,以j开头的数k出现的次数 有 ...

  4. BZOJ2425:[HAOI2010]计数(数位DP)

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

  5. 【BZOJ-1833】count数字计数 数位DP

    1833: [ZJOI2010]count 数字计数 Time Limit: 3 Sec  Memory Limit: 64 MBSubmit: 2494  Solved: 1101[Submit][ ...

  6. bzoj1833: [ZJOI2010]count 数字计数(数位DP+记忆化搜索)

    1833: [ZJOI2010]count 数字计数 题目:传送门 题解: 今天是躲不开各种恶心DP了??? %爆靖大佬啊!!! 据说是数位DP裸题...emmm学吧学吧 感觉记忆化搜索特别强: 定义 ...

  7. 【题解】P2602 数字计数 - 数位dp

    P2602 [ZJOI2010]数字计数 题目描述 给定两个正整数 \(a\) 和 \(b\) ,求在 \([a,b]\) 中的所有整数中,每个数码(digit)各出现了多少次. 输入格式 输入文件中 ...

  8. BZOJ 3652: 大新闻(数位DP+概率论)

    不得不说数位DP和博弈论根本不熟啊QAQ,首先这道题嘛~~~可以分成两个子问题: 有加密:直接算出0~n中二进制每一位为0或为1分别有多少个,然后分位累加求和就行了= = 无加密:分别算出0~n中二进 ...

  9. BZOJ 4521 [CQOI2016]手机号码 - 数位DP

    Description 在$[L, R]$找出有几个数满足两个条件 : 1 : 不同时含有$4$ 和 $8$ 2 : 至少有$3$个相邻的数相同 Solution 非常容易的数位DP, $pos$ 为 ...

随机推荐

  1. Spring3.2.11与Quartz2.2.1整合时内存泄漏的问题的解决

    Quartz是一款定时任务调度的开源框架,使用起来比较方便.并且Spring的support包对Quartz有集成.但是笔者在web应用使用的过程中却遇到了内存泄漏的问题. 问题的产生 笔者在使用Sp ...

  2. 学习 Tornado

    异步编程 预习 lambda Lambda functions can be used wherever function objects are required. They are syntact ...

  3. NOIP2010~2017部分真题总结

    NOIP2010~2017部分真题总结 2010 (吐槽)md这个时候的联赛还只有4题吗? 引水入城 只要发现对于有合法解的地图,每个蓄水厂贡献一段区间这个结论就很好做了 那么\(O(n^3)\)对每 ...

  4. Python3.6全栈开发实例[006]

    6.检查传入字典的每一个value的长度,如果大于2,那么仅保留前两个长度的内容,并将新内容返回给调用者. dic = {"k1": "v1v1", " ...

  5. Nginx学习(1)

    Nginx 是一个高性能的 Web 和反向代理服务器, 它具有有很多非常优越的特性: 作为 Web 服务器:相比 Apache,Nginx 使用更少的资源,支持更多的并发连接,体现更高的效率,这点使 ...

  6. applicationContext.xml配置简介

    这里简单介绍一下spring的配置文件applicationContext.xml中的一些配置的作用. <context:component-scan base-package="&q ...

  7. 找出n的阶乘末尾有几个零

    原理:因为10由2*5组成,而构成2的因数比5多 所以最终转换成求5的个数 int getNumber(int n) { int count = 0; while(n) { n = n/5; coun ...

  8. 我的第三个Python小程序

    99乘法表: # Author: fansik # Description: 99 times table # method 1 num1 = 0 num2 = 0 while num1 < 9 ...

  9. numpy的通用函数:快速的元素级数组函数

    通用函数(ufunc)是对ndarray中的数据执行元素级运算的函数.可看作简单函数的矢量化包装. 一元ufunc sqrt对数组中的所有元素开平方 exp对数组中的所有元素求指数 In [93]: ...

  10. 'is' in Python

    在Python中应该避免将“is”运算符用于比较 像“数值”和“字符串”这种不可变的值.由于Python内部操作这些对象的方式,使得对这些对象使用“is”运算符的结果将是不可预测的. 下面以两个例子加 ...