• Codeforces Round #131 (Div. 1) B. Numbers dp


    题目链接:

    http://codeforces.com/problemset/problem/213/B

    B. Numbers

    time limit per test 2 seconds
    memory limit per test 256 megabytes
    #### 问题描述 > 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. #### 输入 > 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. #### 输出 > On a single line print the remainder of dividing the answer to the problem by 1000000007 (109 + 7). #### 样例 > **sample input** > 3 > 1 1 0 0 0 0 0 0 0 0 > > **sample output** > 36

    note

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

    题意

    给你0到9这十个数字,第i个数至少要用a[i]次,问能拼成的长度小于等于n的正整数(不能有前导零)

    题解

    dp[i][len]表示利用i到9的数字能拼成的长度为len的所有可能数。
    状态转移方程:dp[i][len]=sigma(dp[i+1][len-k]*C[len][k])。
    相当于是在用i+1到9凑成的长度为len-k的数字串里面塞进去k个i的所有可能数。用乘法原理可知去掉已经统计出来的len-k,我们要处理的就是从len里面选k个位置来放i。
    注意:由于前导零不用考虑,而且只要统计正整数,所以我们在放0的时候,是不能让零放在第一位的,对于0我们可以特殊处理一下。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    
    typedef __int64 LL;
    
    const int maxn = 111;
    const int mod = 1e9 + 7;
    
    int dig[22],n;
    LL dp[22][maxn];
    
    LL C[maxn][maxn];
    void pre() {
    	memset(C, 0, sizeof(C));
    	C[0][0] = 1;
    	for (int i = 1; i < maxn; i++) {
    		C[i][0] = 1;
    		for (int j = 1; j <= i; j++) {
    			C[i][j] = C[i - 1][j - 1] + C[i - 1][j];
    			C[i][j] %= mod;
    		}
    	}
    }
    
    int main() {
    	pre();
    	scanf("%d", &n);
    	for (int i = 0; i < 10; i++) {
    		scanf("%d", &dig[i]);
    	}
    	memset(dp, 0, sizeof(dp));
    	dp[10][0] = 1;
    	for (int i = 9; i > 0; i--) {
    		for (int j = 0; j < maxn; j++) {
    			for (int k = dig[i]; k <=j; k++) {
    				dp[i][j] += dp[i + 1][j - k] * C[j][k];
    				dp[i][j] %= mod;
    			}
    		}
    	}
    	for (int j = 0; j < maxn; j++) {
    		for (int k = dig[0]; k < j; k++) {
    			dp[0][j] += dp[1][j - k] * C[j - 1][k];
    			dp[0][j] %= mod;
    		}
    	}
    	LL ans = 0;
    	for (int j = 1; j <= n; j++) {
    		ans += dp[0][j];
    		ans %= mod;
    	}
    	printf("%I64d
    ", ans);
    	return 0;
    }
  • 相关阅读:
    隐藏PHP程序头部发出的:XPoweredBy: PHP/5.2.4类似的信息
    wtai无线应用简单方法
    七大你可能不知道的 Chrome 使用技巧
    常用JS图片滚动(无缝、平滑、上下左右滚动)
    精心挑选12款优秀的 JavaScript 日历和时间选择插件
    JS动态加载JS文件与CSS文件
    通用的JS表单验证插件代码
    dede(织梦)CMS后台的验证码不显示
    Sublime Text2 使用方法及快捷键
    Meta标签详解
  • 原文地址:https://www.cnblogs.com/fenice/p/5701688.html
Copyright © 2020-2023  润新知