[HAOI2010]计数(组合数学)(数位DP)
原题题意也就是给的数的全排列小于原数的个数。
我们可以很容易的想到重复元素的排列个数的公式。
但是我们发现阶乘的话很快就会爆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)的更多相关文章
- BZOJ 2425 [HAOI2010]计数:数位dp + 组合数
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2425 题意: 给你一个数字n,长度不超过50. 你可以将这个数字: (1)去掉若干个0 ( ...
- [luoguP2518][HAOI2010]计数(数位DP)
传送门 重新学习数位DP.. 有一个思路,枚举全排列,然后看看比当前数小的有多少个 当然肯定是不行的啦 但是我们可以用排列组合的知识求出全排列的个数 考虑数位dp 套用数位dp的方法,枚举每一位,然后 ...
- P2518 [HAOI2010]计数 类似数位dp
题意 你有一组非零数字(不一定唯一),你可以在其中插入任意个0,这样就可以产生无限个数.比如说给定{1,2},那么可以生成数字12,21,102,120,201,210,1002,1020,等等. 现 ...
- BZOJ2425 [HAOI2010]计数 【数位dp】
题目 你有一组非零数字(不一定唯一),你可以在其中插入任意个0,这样就可以产生无限个数.比如说给定{1,2},那么可以生成数字12,21,102,120,201,210,1002,1020,等等. 现 ...
- BZOJ_1833_[ZJOI2010]count 数字计数_数位DP
BZOJ_1833_[ZJOI2010]count 数字计数_数位DP 题意: 给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次. 分析: 数位DP f[i][ ...
- BZOJ_1833_[ZJOI2010]_数字计数_(数位dp)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1833 统计\(a~b\)中数字\(0,1,2,...,9\)分别出现了多少次. 分析 数位dp ...
- 【洛谷】2602: [ZJOI2010]数字计数【数位DP】
P2602 [ZJOI2010]数字计数 题目描述 给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次. 输入输出格式 输入格式: 输入文件中仅包含一行两个整数a ...
- BZOJ1833 ZJOI2010 count 数字计数 【数位DP】
BZOJ1833 ZJOI2010 count 数字计数 Description 给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次. Input 输入文件中仅包 ...
- LuoguP2602 [ZJOI2010]数字计数【数位dp】By cellur925
题目传送门 题目大意:给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次. 继续数位dp=w=. 这一次我们不需要记录$pre$啦!(撒花). 因为这次我们需要的 ...
- 洛谷P2602 [ZJOI2010]数字计数 题解 数位DP
题目链接:https://www.luogu.com.cn/problem/P2602 题目大意: 计算区间 \([L,R]\) 范围内 \(0 \sim 9\) 各出现了多少次? 解题思路: 使用 ...
随机推荐
- MySQL批量添加表字段
ALTER TABLE custom ADD contacts2 VARCHAR(50) NOT NULL DEFAULT '' COMMENT '客户联系人2',ADD phone2 VARCHAR ...
- MySQL中函数CONCAT及GROUP_CONCAT函数的使用
一.CONCAT()函数 CONCAT()函数用于将多个字符串连接成一个字符串. 以数据表[user]作为实例: SELECT USER_NAME, SEX FROM USER WHERE USER ...
- PHP - 输出缓存 - 关于ob系列函数和flush函数
偶然机会看到了flush().知道他的神奇功能可以用在异步传输的comet 模式之后,于是我去试了试这个方法.然后翻手册去看了看什么意思.发现它神奇的和ob类函数在一起.有点好奇,先放一放,来说flu ...
- 201671010140. 2016-2017-2 《Java程序设计》java学习第十五周
java学习第十五周 Java的GUI界面设计,框架以及主要部件填充,归置,布局管理,在第十一章和第十二章进行了系统的学习,在这两章的知识奠基下,可以简单的构造一个GUI用户界面,在两周的学习后,可以 ...
- spring MVC模式拦截所有入口方法的入参出参打印
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.serializer.SerializerFeature; im ...
- H5(1)
css布局模型 清楚了CSS 盒模型的基本概念. 盒模型类型, 我们就可以深入探讨网页布局的基本模型了.布局模型与盒模型一样都是 CSS 最基本. 最核心的概念. 但布局模型是建立在盒模型基础之上,又 ...
- IDEA04 工具窗口管理、各种跳转、高效定位、行操作、列操作、live template、postfix、alt enter、重构、git使用
1 工具窗口管理 所有的窗口都是在view -> tools windows 下面的,这些窗口可以放在IDEA的上下左右各个位置:右键某个窗口后选择move to 即可进行位置调整 2 跳转 2 ...
- ActiveMQ 使用文档
一.为什么使用ActiveMQ 在总线的设计中可能会使用到JMS(Java Message Service)通道, Java消息服务(JMS)超越了生产商专有的MOM(Message-Oriented ...
- 在 Windows Azure 上设计多租户应用程序
作者:Suren Machiraju 和 Ralph Squillace 审校:Christian Martinez.James Podgorski.Valery Mizonov 和 Michael ...
- C++ 模板 与 泛型编程
C++ 模板 与 泛型编程 前言 模板有两种:类模板和函数模板 .模板是泛型编程的基础. 什么叫:泛型编程? 使用独立于特定类型的方式进行编程.也就是我们在编程的时候不明确的写上类型,而是使用一个模板 ...