题目链接: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. es 中 for in for of

    arr=[11,22,33,44,55,66,77,88]for (const i in arr){ console.log(i) if (i===4){ console.log(arr[i]) }} ...

  2. javascript实例:点亮灯泡

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. 递归函数(Day15)

    一.递归的定义 在一个函数里面再调用这个函数本身 递归特性 1.必须有一个明确的结束条件 2.每次进入更深一层递归时,问题规模相比于上一次的递归有所减少 二.递归的应用 1.递归函数与三层菜单 men ...

  4. socket()模块和套接字对象的内建方法

    一.socket()模块函数 要使用socket.socket()函数来创建套接字,其语法如下: socket(socket_family,socket_type,protocol=0) 如上所述,s ...

  5. LeetCode:螺旋矩阵【54】

    LeetCode:螺旋矩阵[54] 题目描述 给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素. 示例 1: 输入: [ [ 1, 2, 3 ], ...

  6. Owncloud-X安装配置

    系统是基于Centos7.2 1.更改yum源: mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.back ...

  7. iOS 什么是函数式编程

    前言:当前只做理解性的常规背书,根据不断深入学习会不断丰富解读内容,欢迎评论提意见 函数式编程:Functional Programming 1 基本解释: 函数式编程 是一种思维模式,一种编程思想, ...

  8. iOS URL Loading System / HTTP 重定向 认识与学习

    一个朋友问了我一个问题,需求是这样的:他要用本地的H5资源 替换 链接资源,  但是判断链接资源时候 因为一些操作请求本地化了之后  一些操作比如请求服务器使用的是http开头,然而本地资源一直是以f ...

  9. SOA和微服务之间的区别

    近几年,我们有很多文章对SOA和微服务之间的不同点和相似点进行了分析.有些人认为SOA有很多地方是值得微服务学习的,而有些人则认为区别对待微服务和SOA会更好.而Neal Ford认为,将单体迁移到面 ...

  10. Linux文件系统管理 挂载命令mount

    概述 mount命令用来挂载Linux系统外的文件. Linux 中所有的存储设备都必须挂载之后才能使用,包括硬盘.U 盘和光盘(swap 分区是系统直接调用的,所以不需要挂载).不过,硬盘分区在安装 ...