BZOJ 2425 [HAOI2010]计数:数位dp + 组合数
题目链接: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 + 组合数的更多相关文章
- [HAOI2010]计数 数位DP+组合数
题面: 你有一组非零数字(不一定唯一),你可以在其中插入任意个0,这样就可以产生无限个数.比如说给定{1,2},那么可以生成数字12,21,102,120,201,210,1002,1020,等等. ...
- bzoj 2425 [HAOI2010]计数 dp+组合计数
[HAOI2010]计数 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 451 Solved: 289[Submit][Status][Discus ...
- BZOJ 1833 数字计数 数位DP
题目链接 做的第一道数位DP题,听说是最基础的模板题,但还是花了好长时间才写出来..... 想深入了解下数位DP的请点这里 先设dp数组dp[i][j][k]表示数位是i,以j开头的数k出现的次数 有 ...
- BZOJ2425:[HAOI2010]计数(数位DP)
Description 你有一组非零数字(不一定唯一),你可以在其中插入任意个0,这样就可以产生无限个数.比如说给定{1,2},那么可以生成数字12,21,102,120,201,210,1002,1 ...
- 【BZOJ-1833】count数字计数 数位DP
1833: [ZJOI2010]count 数字计数 Time Limit: 3 Sec Memory Limit: 64 MBSubmit: 2494 Solved: 1101[Submit][ ...
- bzoj1833: [ZJOI2010]count 数字计数(数位DP+记忆化搜索)
1833: [ZJOI2010]count 数字计数 题目:传送门 题解: 今天是躲不开各种恶心DP了??? %爆靖大佬啊!!! 据说是数位DP裸题...emmm学吧学吧 感觉记忆化搜索特别强: 定义 ...
- 【题解】P2602 数字计数 - 数位dp
P2602 [ZJOI2010]数字计数 题目描述 给定两个正整数 \(a\) 和 \(b\) ,求在 \([a,b]\) 中的所有整数中,每个数码(digit)各出现了多少次. 输入格式 输入文件中 ...
- BZOJ 3652: 大新闻(数位DP+概率论)
不得不说数位DP和博弈论根本不熟啊QAQ,首先这道题嘛~~~可以分成两个子问题: 有加密:直接算出0~n中二进制每一位为0或为1分别有多少个,然后分位累加求和就行了= = 无加密:分别算出0~n中二进 ...
- BZOJ 4521 [CQOI2016]手机号码 - 数位DP
Description 在$[L, R]$找出有几个数满足两个条件 : 1 : 不同时含有$4$ 和 $8$ 2 : 至少有$3$个相邻的数相同 Solution 非常容易的数位DP, $pos$ 为 ...
随机推荐
- 将CodedUI Test 放到控制台程序中,模拟鼠标键盘操作
CodedUI Test是微软的自动化测试工具,在VS中非常好用.可以用来模拟鼠标点击,键盘输入.但执行的时候必须要用mstest调用,无法传入参数(当然可以写入config文件中,但每次修改十分麻烦 ...
- https nginx openssl 自签名
公私钥:公钥可以唯一解密私钥加密过的数据,反之亦然.以下用P指代公钥,V指代私钥.SSL过程:需要两对公私钥(P1,V1),(P2,V2),假设通信双方是A和B,B是服务器,A要确认和它通信的是B:A ...
- vb.net 正則表達式 取 固定格式的字符
vb.net 正則表達式 取 固定格式的字符: 原始字符串:strSqlTmp="select * from A_TEST where a_data = '@1@' and b_link = ...
- where VS having
where 和 having 的区别: WHERE 子句不能包含聚集函数: 因为试图用聚集函数判断那些行输入给聚集运算是没有意义的.相反,HAVING 子句总是包含聚集函数 hav ...
- 201704 F-47创建预付款申请a
应该也是用 BAPI_ACC_DOCUMENT_POST
- python之网络socket编程
一.网络协议 客户端/服务器架构 1.硬件C/S架构(打印机) 2.软件C/S架构(互联网中处处是C/S架构):B/S架构也是C/S架构的一种,B/S是浏览器/服务器 C/S架构与socket的关系: ...
- LeetCode:二叉树的锯齿形层次遍历【103】
LeetCode:二叉树的锯齿形层次遍历[103] 题目描述 给定一个二叉树,返回其节点值的锯齿形层次遍历.(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行). 例如:给定二叉树 ...
- 类百度DOC编辑区域
.mainarea{ position:absolute; top:151px; width:100%; bottom:0px; } .edit_wrap{ background:#fcfcfc; p ...
- iOS 11系列 - Xcode 9新特性
Xcode 9最近刚刚发布,带来了一系列不错的新特性,可以更好的帮助到开发者完成开发工作. Xcode Runtime Tool Xcode 9中有许多Runtime Tool可以帮助开发者找到代码错 ...
- 【HackerRank】Game Of Rotation
题目连接:Game Of Rotation Mark is an undergraduate student and he is interested in rotation. A conveyor ...