题干:

Furik loves writing all sorts of problems, especially such that he can't solve himself. You've got one of his problems, the one Furik gave to Rubik. And Rubik asks you to solve it.

There is integer n and array a, consisting of ten integers, indexed by numbers from 0 to 9. Your task is to count the number of positive integers with the following properties:

  • the number's length does not exceed n;
  • the number doesn't have leading zeroes;
  • digit i (0 ≤ i ≤ 9) occurs in the number at least a[i] times.

Input

The first line contains integer n (1 ≤ n ≤ 100). The next line contains 10 integers a[0], a[1], ..., a[9] (0 ≤ a[i] ≤ 100) — elements of array a. The numbers are separated by spaces.

Output

On a single line print the remainder of dividing the answer to the problem by 1000000007 (109 + 7).

Examples

Input

1
0 0 0 0 0 0 0 0 0 1

Output

1

Input

2
1 1 0 0 0 0 0 0 0 0

Output

1

Input

3
1 1 0 0 0 0 0 0 0 0

Output

36

Note

In the first sample number 9 meets the requirements.

In the second sample number 10 meets the requirements.

In the third sample numbers 10, 110, 210, 120, 103 meet the requirements. There are other suitable numbers, 36 in total.

解题报告:

dp[i][j]表示:长度为i,用1~j数字所能构成的解的方案数。0的那一位单独处理就可以了、、

AC代码:(62ms)

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
#define fi first
#define se second
using namespace std;
const int MAX = 4e5 + 5;
const ll mod = 1000000000+7;int n;
int a[15];
ll dp[150][22];
ll C[205][205];
void init() {C[0][0]=1;for(int i=1; i<=100; i++) {C[i][0]=1;for(int j=1; j<=i; j++) {C[i][j]=(C[i-1][j-1]+C[i-1][j])%mod;}}
}
int main()
{init();cin>>n;for(int i = 0; i<=9; i++) scanf("%d",a+i);for(int i = a[1]; i<=n; i++) dp[i][1] = 1;//长度为i只包含1的 、for(int i = 1; i<=9; i++) {for(int j = 0; j<=n; j++) {for(int k = a[i]; k<=j; k++) {dp[j][i] = (dp[j][i] + dp[j-k][i-1]*C[j][k])%mod;}}}for(int i = 0; i<=n; i++) {for(int k = a[0]; k<i; k++) {dp[i][0] = (dp[i][0]+dp[i-k][9]*C[i-1][k])%mod;}}ll ans = 0;for(int i = 0; i<=n; i++) ans = (ans + dp[i][0]) % mod;printf("%lld\n",ans);return 0 ;}

关于组合数的求法,还有一种92ms的,,打表到1e5才92ms、、、可以一试啊反正是On的、、

const ll mod = 1000000000+7;
const ll N = 300000+5;
const ll M = 3e5+3;
int n;
ll fac[1000005];            //阶乘
ll inv_of_fac[1000005];        //阶乘的逆元
int a[15];
ll dp[150][12];
ll qpow(ll x,ll n)
{ll ret=1;for(; n; n>>=1){if(n&1) ret=ret*x%mod;x=x*x%mod;}return ret;
}
void init()
{fac[1]=1;for(int i=2; i<=M; i++)fac[i]=fac[i-1]*i%mod;inv_of_fac[M]=qpow(fac[M],mod-2);for(int i=M-1; i>=0; i--)inv_of_fac[i]=inv_of_fac[i+1]*(i+1)%mod;//inv_of_fac[i]=qpow(fac[i],mod-2);//为什么不行啊 //也行
}
ll C(ll a,ll b)
{if(b>a) return 0;if(b==0) return 1;return fac[a]*inv_of_fac[b]%mod*inv_of_fac[a-b]%mod;
}

附:

三套代码的dp思路以后看

#include <bits/stdc++.h>
using namespace std;
#define N 202
#define mod 1000000007typedef long long LL;int n, a[N], s[N];
LL c[N][N], f[N][N], ans;void prepare() {c[0][0] = 1;for (int i = 1; i <= 200; i ++) {c[i][0] = 1;for (int j = 1; j <= i; j ++) c[i][j] = (c[i-1][j] + c[i-1][j-1]) % mod;}
}
inline LL h(int n, int k) {return c[n+k-1][k];
}
int main() {prepare();scanf("%d", &n);for (int i = 0; i <= 9; i ++) scanf("%d", &a[i]);for (int i = 1; i <= 9; i ++) s[i] = s[i-1] + a[i];int sum = s[9];f[0][0] = 1;for (int i = 1; i <= 9; i ++) {for (int j = s[i-1]; j <= n; j ++) {for (int k = a[i]; k <= n - j; k ++) {f[i][j+k] = (f[i][j+k] + f[i-1][j] * c[j+k][j]) % mod;}}}for (int zero = a[0]; zero <= n; zero ++) {for (int other = sum; other <= n - zero; other ++) {ans = (ans + f[9][other] % mod * h(other, zero)) % mod;}}printf("%I64d\n", ans);return 0;
}

代码2

#include<cstdio>
#include<cstring>
int f[15][105];
int d[15];
int n;
int mod=1000000007;
int c[105][105];
int main() {c[0][0]=1;for(int i=1; i<=100; i++) {c[i][0]=1;for(int j=1; j<=i; j++) c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod;}scanf("%d",&n);int sum=0;int ans=0;for(int i=0; i<10; i++) {scanf("%d",d+i);sum+=d[i];}for(int i=1; i<=n; i++) {memset(f,0,sizeof(f));f[0][i]=1;for(int j=0; j<10; j++) {for(int k=0; k<=i; k++)if (f[j][k]) {for(int l=d[j]; l<=k; l++)f[j+1][k-l]=(f[j+1][k-l]+1ll*f[j][k]*c[k][l]%mod)%mod;}}ans=(ans+f[10][0])%mod;}n--;if (d[0]) {d[0]--;}for(int i=0; i<=n; i++) {memset(f,0,sizeof(f));f[0][i]=1;for(int j=0; j<10; j++) {for(int k=0; k<=i; k++)if (f[j][k]) {for(int l=d[j]; l<=k; l++)f[j+1][k-l]=(f[j+1][k-l]+1ll*f[j][k]*c[k][l]%mod)%mod;}}//printf("%d\n",f[10][0]);ans=(ans-f[10][0])%mod;}ans=(ans+mod)%mod;printf("%d\n",ans);
}

代码3:

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;int a[10];
long long f[10][200];
long long C[300][300];
int main() {long long mod=1000000007;for (int i=1; i<=200; i++) {C[i][i]=C[i][0]=1;}C[0][0]=1;for (int i=2; i<=200; i++)for (int j=1; j<i; j++) {C[i][j]=C[i-1][j-1]+C[i-1][j];C[i][j]%=mod;}int n;cin>>n;int tot=0;for (int i=0; i<10; i++) {cin>>a[i];tot+=a[i];}memset(f,0,sizeof(f));for(int i=a[9]; i<=n; i++) {f[9][i]=1;}for (int i=8; i>0; i--) {if (a[i]==0) f[i][0]=f[i+1][0];for (int j=1; j<=n; j++)for (int k=a[i]; k<=j; k++) {f[i][j]+=f[i+1][j-k]*C[j][k];f[i][j]%=mod;}}for (int j=2; j<=n; j++)for (int k=a[0]; k<j; k++) {f[0][j]+=f[1][j-k]*C[j-1][k];f[0][j]%=mod;}// cout<<f[1][1]<<' '<<f[1][2]<<endl;long long ans=0;if (a[0]==0) {ans+=f[1][1];}for (int i=2; i<=n; i++) {ans+=f[0][i];ans%=mod;}cout<<ans%mod<<endl;
}

*【CodeForces - 214D 】Numbers (dp,组合数学)相关推荐

  1. CodeForces 215 E.Periodical Numbers(组合数学+dp)

    Description 给出一个区间[L,R][L,R],问这个区间中有多少数字的二进制表示是有循环节的 Input 两个正整数L,RL,R(1≤L≤R≤1018)(1\le L\le R\le 10 ...

  2. D - Yet Another Problem On a Subsequence CodeForces - 1000D (DP,组合数学)

    D - Yet Another Problem On a Subsequence CodeForces - 1000D The sequence of integers a1,a2,-,aka1,a2 ...

  3. CodeForces - 336D Vasily the Bear and Beautiful Strings(dp+组合数学)

    题目链接:点击查看 题目大意:给出一个 01 字符串,规定求值的过程如下: 每次选择末尾的两个数字: 如果为 0 0 ,那么替换成一个 1 否则替换成一个 0 循环往复,直至只剩一个数字位置,剩下的数 ...

  4. CodeForces 285 E.Positions in Permutations(dp+组合数学)

    Description 定义一个排列的权为满足|pi−i|=1|p_i-i|=1的ii的个数,问长度为nn的排列且权为kk的有多少个 Input 两个整数n,k(1≤n≤1000,0≤k≤n)n,k( ...

  5. Codeforces 833B 题解(DP+线段树)

    题面 传送门:http://codeforces.com/problemset/problem/833/B B. The Bakery time limit per test2.5 seconds m ...

  6. CodeForces 864E Fire dp递推

    CodeForces 864E 题意:有 n 个物品着火,每个物品要花 ti 时间扑灭,且在 >= di 时间后就会坏掉,物品价值为 pi . 问最多可以救回多少价值,物品个数,及救哪些物品(要 ...

  7. Codeforces 864E - Fire(dp)

    原题连接:http://codeforces.com/problemset/problem/864/E 题意:一个人想从大火中带走一些东西.每次他只能带一个,耗时ti ,价值为pi, 当总时间超过di ...

  8. CodeForces - 1497D Genius(dp)

    题目链接:点击查看 题目大意:给出 nnn 个问题,每个问题有如下属性: tagtagtag:标签 ccc:困难度 sss:奖励值 初始时 ci=2ic_i=2^ici​=2i,初始时 IQ=0IQ= ...

  9. ZOJ - 4114 Flipping Game(dp+组合数学)

    题目链接:点击查看 题目大意:给出一个长度为 n 的 01 字符串表示 n 个灯泡的状态,1 为点亮,0 为熄灭,现在需要进行 k 轮操作,每轮操作可以选择恰好 m 个位置,将灯泡的状态置反,现在给出 ...

最新文章

  1. -y表示自动安装,不需要每项手动确认输入 Yes
  2. Google的预训练模型又霸榜了,这次叫做T5(附榜单)
  3. Silverlight 解谜游戏 之三 消除名单
  4. VTK:可视化之VectorOfActors
  5. AC_Automata模板
  6. internetreadfile读取数据长度为0_【完结】TensorFlow2.0 快速上手手册
  7. notepad++ json插件_Emmet--Web前端工具,需要安装插件在sublime里
  8. jquery中filter(fn)的使用研究
  9. 设备树解析过程及platform设备注册
  10. 银行笔试 - 数据库基础知识总结
  11. Matlab 四阶龙格库塔法求解二元常微分方程组
  12. 简单了解几种常见的网络通信协议
  13. vue-amap使用教程
  14. 【SAP】实施方法论-ASAP
  15. 数据风云、十年变迁(DTCC会议总结)
  16. 国产麒麟操作系统kylin V10 sp2操作系统安装openldap和kerberos
  17. Cloudera Manager5.14.3集群搭建
  18. css案例1——一级菜单、二级菜单、三级菜单、四级菜单
  19. Docker软件安装文档
  20. Unity3D UGUI 渐变效果

热门文章

  1. [剑指offer]面试题第[1]题[JAVA][二维数组中的查找][数组][二分]
  2. elementui图片上传php,vue+element-ui+富文本————图片上传
  3. 5 html 根据手机转动而转动_手机安装陀螺仪有什么用 手机安装陀螺仪作用介绍【详解】...
  4. python多线程编程_Python 多线程编程
  5. python卸载opencv_20.Windows python,opencv的安装与卸载
  6. 四阶混合累积量matlab_12m氢燃料电池城市客车电电混合动力系统设计方案
  7. res.status === 200含义
  8. android 日历仿IOS,基于Android week view仿小米和iphone日历效果
  9. 真实AIS数据,解码,可视化
  10. python调用mysql数据库sql语句过长有问题吗_python连接MYSQL数据库,调用update语句后无法更新数据,解决...