P2518 [HAOI2010]计数
题目描述
你有一组非零数字(不一定唯一),你可以在其中插入任意个0,这样就可以产生无限个数。比如说给定{1,2},那么可以生成数字12,21,102,120,201,210,1002,1020,等等。
现在给定一个数,问在这个数之前有多少个数。(注意这个数不会有前导0).
输入格式
只有1行,为1个整数n.
输出格式
只有整数,表示N之前出现的数的个数。
输入
1020
输出
7
说明/提示
n的长度不超过50,答案不超过2^63-1.
代码:
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1010;
char c;
long long ans;
int n,a[N],v[N];
long long dp[N][N];
long long C(long long n,long long m) {
if(dp[n][m])
return dp[n][m];
if(m==1)
return n;
if(m==0||m==n)
return 1;
if(m>n)
return 0;
dp[n][m]=C(n-1,m)+C(n-1,m-1);
return dp[n][m];
}
long long cfb() {
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;
}
bool check(char x) {
return (x>='0'&&x<='9');
}
int main () {
while(~scanf("%c",&c))
if(check(c)) {
v[++n]=c-'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+=cfb();
a[j]++;
}
a[v[i]]--;
}
printf("%lld\n",ans);
return 0;
}

浙公网安备 33010602011771号