您的位置:首页 > 其它

Codeforces Round #131 Div1 B

2016-01-01 08:03 471 查看

Problem


给出Ai(i∈[0,9])A_i(i\in[0,9])。表示每一个数字至少须要出现多少次。问有多少个数满足下面三个条件:1. 数至多有NN位;2. 数不含有前导0;3. 每一个数 ii 出现的次数不少于AiA_i(mod 1e9+7)



Limits


TimeLimit(ms):2000Time Limit(ms): 2000

MemoryLimit(MB):256Memory Limit(MB): 256

N∈[1,100]N\in[1,100]

Ai∈[0,100]A_i \in[0,100]



Look up Original Problem From here

Solution


实际上是一种填数、计数统计的问题。

考虑填0的情况。在此基础上。考虑填1的情况。…。最后考虑填9的情况。

因为不可含有前导0,最好还是先枚举如果第一个数字,而剩下的N-1N-1位数字进行填数。设dp[i][j]dp[i][j]表示当前填下的这个数为 i,数的长度是 j 时有多少个数满足题意。

转移方程:dp[now][i+j]=dp[now][i+j]+dp[now−1][j]×Cin−jdp[now][i+j]=dp[now][i+j]+dp[now-1][j]\times C_{n-j}^i。统计答案,ans=∑nj=0(dp[9][j]Cn−jn)ans=\sum_{j=0}^n(\frac{dp[9][j]}{C_n^{n-j}})。除法不满足取模运算。用逆元解决。



Complexity


TimeComplexity:O(9⋅9⋅N2)Time Complexity: O(9\cdot 9\cdot N^2)

MemoryComplexity:O(N2)Memory Complexity: O(N^2)



My Code

//Hello. I'm Peter.
#include<cstdio>
#include<iostream>
#include<sstream>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<cctype>
#include<ctime>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
typedef long double ld;
const double pi=acos(-1.0);
#define peter cout<<"i am peter"<<endl
#define randin srand((unsigned int)time(NULL))
#define INT (0x3f3f3f3f)*2
#define LL (0x3f3f3f3f3f3f3f3f)*2
#define input freopen("data.txt","r",stdin)
#define gsize(a) (int)a.size()
#define len(a) (int)strlen(a)
#define slen(s) (int)s.length()
#define clr(a) memset(a,0,sizeof(a))
#define clr_queue(q) while(!q.empty()) q.pop()
#define clr_stack(s) while(!s.empty()) s.pop()
#define rep(i, a, b) for (int i = a; i < b; i++)
#define dep(i, a, b) for (int i = a; i > b; i--)
#define repin(i, a, b) for (int i = a; i <= b; i++)
#define depin(i, a, b) for (int i = a; i >= b; i--)
#define esp 1e-6
#define MAXN
#define N 200
#define M
const ll mod=1e9+7;
ll C

,ans,dp[15]
;
int n,a
,sum;
void init_C(){
clr(C);
rep(i,0,N){
C[i][0]=1;
}
rep(i,1,N){
rep(j,1,N){
C[i][j]=(C[i-1][j-1]+C[i-1][j])%mod;
}
}
}
ll quick_power(ll x,ll y){
if(!y) return 1;
ll res=quick_power(x,y>>1);
res=res*res%mod;
if(y%2) res=res*x%mod;
return res;
}
int main(){
init_C();
ans=0;
scanf("%d",&n);
rep(i,0,10){
scanf("%d",a+i);
}
repin(de,1,9){
a[de]-=1;
n-=1;
repin(i,0,9){
repin(j,0,n){
dp[i][j]=0;
}
}
repin(i,0,n){
if(i>=a[0]) dp[0][i]=C
[i];
}
repin(now,1,9){
repin(i,0,n){
if(i<a[now]) continue;
repin(j,0,n){
if(i+j>n || !dp[now-1][j]) continue;
dp[now][i+j]=(dp[now][i+j]+dp[now-1][j]*C[n-j][i])%mod;
}
}
}
repin(i,0,n){
//            ans=(ans+dp[9][i]/C
[n-i]); 不能直接求。转化为逆元来做。
ans=(ans+dp[9][i]*quick_power(C
[n-i],mod-2))%mod;
}
n+=1;
a[de]+=1;
}
printf("%lld\n",ans);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: