原题题意也就是给的数的全排列小于原数的个数。

我们可以很容易的想到重复元素的排列个数的公式。

但是我们发现阶乘的话很快就会爆long long啊(如果您想写高精请便)

之后我就尝试质因数分解。。。。但是遗憾的是太蒻了,没有成功,还是爆了。20分惨惨。最后也没有找出来哪里错了。

最后蒟蒻只好参考题解了。。。。。

之后我们再一考虑,会发现其实我们不需要重复元素排列个数的公式,我们只需要按照组合数的思想做即可。

假设我们现在有m个位置可以摆放,我们先放0,个数就是\(C_m^{cnt[0]}\),之后就只剩\(m-cnt[0]\)个位置了,那么\(ans+=C_{m-cnt[0]}^{cnt[1]}\)。。以此类推。。。

#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
long long CC[1001][1001];
long long C(long long n,long long m){
if(CC[n][m]) return CC[n][m];
if(m==1) return n;
if(m==0||m==n) return 1;
if(m>n) return 0;
CC[n][m]=C(n-1,m)+C(n-1,m-1);
return CC[n][m];
}
int a[10],v[100];
long long ans;
int n;
string c;
long long solve(){
long long ans=1;
int m=n;
for(int i=0;i<=9;i++)
if(a[i])
ans*=C(m,a[i]),m-=a[i];
return ans;
}
int main()
{
cin>>c;
for(int i=0;i<c.length();i++)
v[++n]=c[i]-'0',a[v[n]]++;
int nn=n;
for(int i=1;i<=nn;i++)
{
n--;
for(int j=0;j<v[i];j++)
if(a[j])
a[j]--,ans+=solve(),a[j]++;
a[v[i]]--;
}
printf("%lld",ans);
}

最后蒟蒻在这里贴上自己的20分代码。。求dalao找错。。。。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<vector>
using namespace std;
long long ans;
vector<int>v;
string n;
int dig[60],sum[10]; inline long long solve(int cnt)
{
long long cur_ans=1;
int a[60];
memset(a,0,sizeof(a));
for(int i=1;i<=cnt;i++)
{
int now=i;
for(int j=2;j<=now;j++)
while(now%j==0)
now/=j,a[j]++;//printf("a[%d]=%d\n",j,a[j]);
}
for(int i=0;i<=9;i++)
{
if(sum[i]==0) continue;
int now=sum[i];
for(int j=2;j<=now;j++)
while(now%j==0)
now/=j,a[j]--;//printf("a[%d]=%d\n",j,a[j]);
}
for(int i=1;i<=50;i++)
if(a[i]!=0)
cur_ans*=(long long)pow(i,a[i]);
return cur_ans;
} int main()
{
cin>>n;
for(int i=0;i<n.length();i++)
v.push_back(n[i]-'0');
int cnt=v.size();
for(int i=0;i<v.size();i++)dig[i+1]=v[i];
//for(int i=1;i<=cnt;i++) cout<<dig[i];
//cout<<endl;
for(int i=1;i<=cnt;i++)
{
int done[10];
memset(done,0,sizeof(done));
for(int j=i+1;j<=cnt;j++)
{
memset(sum,0,sizeof(sum));
if(done[dig[j]]==0&&dig[j]<dig[i])
{
done[dig[j]]=1;
for(int k=i+1;k<=cnt;k++)
sum[dig[k]]++;
sum[dig[i]]++;
sum[dig[j]]--;
ans+=(long long)solve(cnt-i);
//printf("dig[%d]=%d dig[%d]=%d ans=%lld\n",i,dig[i],j,dig[j],ans);
}
}
}
printf("%lld\n",ans);
return 0;
}

[HAOI2010]计数(组合数学)(数位DP)的更多相关文章

  1. BZOJ 2425 [HAOI2010]计数:数位dp + 组合数

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2425 题意: 给你一个数字n,长度不超过50. 你可以将这个数字: (1)去掉若干个0 ( ...

  2. [luoguP2518][HAOI2010]计数(数位DP)

    传送门 重新学习数位DP.. 有一个思路,枚举全排列,然后看看比当前数小的有多少个 当然肯定是不行的啦 但是我们可以用排列组合的知识求出全排列的个数 考虑数位dp 套用数位dp的方法,枚举每一位,然后 ...

  3. P2518 [HAOI2010]计数 类似数位dp

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

  4. BZOJ2425 [HAOI2010]计数 【数位dp】

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

  5. BZOJ_1833_[ZJOI2010]count 数字计数_数位DP

    BZOJ_1833_[ZJOI2010]count 数字计数_数位DP 题意: 给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次. 分析: 数位DP f[i][ ...

  6. BZOJ_1833_[ZJOI2010]_数字计数_(数位dp)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1833 统计\(a~b\)中数字\(0,1,2,...,9\)分别出现了多少次. 分析 数位dp ...

  7. 【洛谷】2602: [ZJOI2010]数字计数【数位DP】

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

  8. BZOJ1833 ZJOI2010 count 数字计数 【数位DP】

    BZOJ1833 ZJOI2010 count 数字计数 Description 给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次. Input 输入文件中仅包 ...

  9. LuoguP2602 [ZJOI2010]数字计数【数位dp】By cellur925

    题目传送门 题目大意:给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次. 继续数位dp=w=. 这一次我们不需要记录$pre$啦!(撒花). 因为这次我们需要的 ...

  10. 洛谷P2602 [ZJOI2010]数字计数 题解 数位DP

    题目链接:https://www.luogu.com.cn/problem/P2602 题目大意: 计算区间 \([L,R]\) 范围内 \(0 \sim 9\) 各出现了多少次? 解题思路: 使用 ...

随机推荐

  1. HTTP 1.0 & 1.1

    简介: HTTP ( HyperText Transfer Protocol ) 超文本传输协议,是互联网上应用最广泛的一种网络协议. HTTP 是一个客户端和服务端请求.应答的标准.使用 WEB 浏 ...

  2. Linux任务前后台的切换(转)

    Linux任务前后台的切换   Shell支持作用控制,有以下命令实现前后台切换: 1. command& 让进程在后台运行 2. jobs 查看后台运行的进程 3. fg %n 让后台运行的 ...

  3. loadView 和 viewDidLoad、viewDidunload 的区别

    loadView 和 viewDidLoad 是 iPhone 开发中肯定要用到的两个方法. 他们都可以用来在视图载入的时候初始化一些内容. 但是他们有什么区别呢? viewDidLoad 方法只有当 ...

  4. spring注解扫描组件注册

    最近对单点系统进行微服务拆分,被各个springboot的组件注册搞得云里雾里的.(有的是通过springboot的自动配置进IOC容器的,有的是自己添加构造方法添加进IOC容器.)决定抽时间将spr ...

  5. visjs使用小记-1.创建一个简单的网络拓扑图

    1.插件官网:http://visjs.org/ 2.创建一个简单的网络拓扑图 <!doctype html> <html> <head> <title> ...

  6. 批量判断网页是否NOT found

    import java.net.HttpURLConnection;import java.net.URL; public class NetValible{ static String[] url ...

  7. FreeSWITCH 客户端fs_cli连接设置(acl)

    FreeSWITCH 默认配置只能 在本机连接, 要从 外面连接, 就要配置: acl.conf.xml::network-lists/list event_socket.conf.xml::appl ...

  8. web.xml配置详解[转]

    引文: 对于一个J2EE领域的程序员而言,基本上每天都会和web应用打交道. 什么是web应用?最简单的web应用什么样?给你一个web应用你该从何入手? 1.什么是web应用? web应用是一种可以 ...

  9. [SoapUI] JsonPath 语法 与 XPath 对比

    XPath JSONPath Description / $ the root object/element . @ the current object/element / . or [] chil ...

  10. funk_SVD 个人理解

    目标函数: $ J = \frac{1}{2} \left\| R - PQ \right\|^{2} + \lambda \left( \left\|P \right\|^{2} +\left\| ...