题目大意

给出一个数字$n$,求满足下列条件的数$x$的个数:

  1. $x<n$
  2. 对于来自于$x$十进制各个数位上的非零数字,它们的种类与个数都与$n$的相同。

思路

入手点

  设$n$有$t$位数字,如果满足上述条件的$x$的位数$t'$比$t$小,那相当于$x$前面含有$t-t'$个前缀0!因此如果我们不考虑第1条,那么$x$就是由$n$各个位上数字包括0组成的全排列。

考虑第一条

  我们定义$a_i$为数$n$在第$i$位上的数字,$b_i$则是$x$的。$f(m)$为当$n$与$x$在$m$以上的位数都相等的情况下,满足题目条件的排列个数。若$a_m=b_m$,则转化为子问题$f(m-1)$;如果$b_m<a_m$,则$x$位数比$m$小的那部分无论如何排列,都会满足第一条,故结果为:对于每一个$b_m\in[0,a_m)$,将其锁定在第$m$位,$n$在$m$及以下的位数的所有数字排除掉被安在第一位的$b_m$后,在$m-1$个数中的全排列。由加法原理,这些结果都要相加

怎么求含可重元素的全排列

  已知一个数组,$h_i$表示一个元素的个数,在长度$m$的区间里求它的全排列。其相当于先在区间中安0,共有$C_m^{h_0}$种选法;然后再在剩余的空间$m-h_0$中看看1的安放方式,即$C_{m-h_0}^{h_1}$。以此类推。根据乘法原理,这些组合数要相乘才为结果

注意事项

  • ans用long long!
  • 求组合数递归时不要忘了给C数组赋值!
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <stack>
#include <cstdlib>
#include <iostream>
using namespace std; #define ll long long
const int MAX_DIGIT = 55, MAX_NUM = 10;
ll A[MAX_DIGIT];
int NumCnt[MAX_NUM];
ll C[MAX_DIGIT][MAX_DIGIT]; ll Comb(int n, int m)
{
if (n < 0 || m < 0)
return 0;
if (C[n][m])
return C[n][m];
else if (m == 0 || m == n)
return C[n][m] = 1;
else if (m == 1)
return C[n][m] = n;
else if (m > n)
return 0;
else
return C[n][m] = Comb(n - 1, m - 1) + Comb(n - 1, m);
} ll GetAns(const int len)
{
if (len == 1)
return 0;
ll ans = 0;
for (int firstNum = 0; firstNum < A[len]; firstNum++)
{
NumCnt[firstNum]--;
int subLen = len - 1;
ll combAns = 1;
for (int num = 0; num < 10; num++)
{
combAns *= Comb(subLen, NumCnt[num]);
subLen -= NumCnt[num];
}
NumCnt[firstNum]++;
ans += combAns;
}
NumCnt[A[len]]--;
ans += GetAns(len - 1);
return ans;
} int main()
{
stack<int> st;
char c;
while (cin >> c && isdigit(c))
st.push(c - '0');
int len = 0;
while (!st.empty())
{
A[++len] = st.top();
NumCnt[A[len]]++;
st.pop();
}
cout << GetAns(len) << endl;
return 0;
}

  

luogu2518 [HAOI2010] 计数的更多相关文章

  1. 【BZOJ2425】[HAOI2010]计数(组合数学)

    [BZOJ2425][HAOI2010]计数(组合数学) 题面 BZOJ 洛谷 题解 很容易的一道题目. 统计一下每个数位出现的次数,然后从前往后依次枚举每一位,表示前面都已经卡在了范围内,从这一位开 ...

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

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

  3. BZOJ2425: [HAOI2010]计数

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2425 其实能够构成的数就是原数的排列(算前导0),然后组合计数一下就可以了. #include ...

  4. P2518 [HAOI2010]计数

    题目链接 \(Click\) \(Here\) 很好很妙的一个题目. 其实可以生成的数字,一定是原数的一个排列,因为\(0\)被放在前面就可以认为不存在了嘛~.也就是说现在求的就是全排列中所有小于该数 ...

  5. bzoj千题计划178:bzoj2425: [HAOI2010]计数

    http://www.lydsy.com/JudgeOnline/problem.php?id=2425 题意转化: 给定一个集合S,求S的全排列<给定排列 的排列个数 从最高位开始逐位枚举确定 ...

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

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

  7. [HAOI2010]计数(组合数学)(数位DP)

    原题题意也就是给的数的全排列小于原数的个数. 我们可以很容易的想到重复元素的排列个数的公式. 但是我们发现阶乘的话很快就会爆long long啊(如果您想写高精请便) 之后我就尝试质因数分解....但 ...

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

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

  9. BZOJ2425:[HAOI2010]计数——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=2425 https://www.luogu.org/problemnew/show/P2518 你有 ...

随机推荐

  1. max-age 和 Expires

    网页的缓存是由HTTP消息头中的“Cache-control”来控制的,常见的取值有private.no-cache.max-age.must-revalidate等,默认为private.   Ex ...

  2. 2018年排名前20的数据科学Python库

    Python 在解决数据科学任务和挑战方面继续处于领先地位.业已证明最有帮助的Python库,我们选择 20 多个库,因为其中一些库是相互替代的,可以解决相同的问题.因此,我们将它们放在同一个分组. ...

  3. spring - quartz - experssion 表达式

    字段 允许值 允许的特殊字符 秒 0-59 , - * / 分 0-59 , - * / 小时 0-23 , - * / 日期 1-31 , - * ? / L W C 月份 1-12 或者 JAN- ...

  4. C++:C++在图片特定区域之外产生随机数

    参考原文:C++产生随机数 (整数) C++在图片特定区域之外产生随机数,避开正则表达式,可以分为两种情况. 第一种:在某个数之前生成随机数:第二种,生成随机数,加上某个数,然后截断:第三种,指定范围 ...

  5. AI.框架理论.语义网.语言间距.孤单

    刷个博客,转载自于科学网:AI.框架理论.语义网.语言间距.孤单 一:引言: AI几乎是计算机科学家的梦想,自动化比计算机发展的要早的多.早期的自动化节省了大量人力,激发了人类懒惰的滋长和对自身进化缓 ...

  6. Dijkstra的双栈算术表达式求值算法 C++实现

    #include<iostream> #include<string> using namespace std; template<typename T> clas ...

  7. 2016年8月17日 内省(1)18_黑马程序员_使用beanUtils操纵javabean

    8.内省(1):18_黑马程序员_使用beanUtils操纵javabean 1.导入两个包: 2.调用静态方法. 9.泛型 map.entrySet() :取出map集合的键值对组成一个set集合. ...

  8. vue中eventbus 多次触发的问题

    相比于react,vue是一个更上手很快的框架.所说简单易用,但在做Vue项目的过程中,就会发现,坑还是有的.组件之间传递数据是一个常见的需求,父子组件传递数据在官网有介绍,除了父子组件,一般地,任意 ...

  9. shell脚本操作mysql数据库,使用mysql的-e参数可以执行各种sql的(创建,删除,增,删,改、查)等各种操作

    mysql  -hhostname -Pport -uusername -ppassword  -e  相关mysql的sql语句,不用在mysql的提示符下运行mysql,即可以在shell中操作m ...

  10. eas之动态刷新Table

    如何刷新表体数据行(表头不变) 示例1:删除所有表体行,并重新发取数事件该方法不会修改原先的绑定信息table.removeRows(); 示例2:删除所有表体行,修改绑定信息并重新取数指定新的que ...