zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    实现微信朋友圈点击评论按钮时cell上移
    UITableView的横向使用
    用Xcode6的Leaks检测内存泄漏
    IOS8设备连接XCODE6真机调试报错"Could not inspect the application package"
    Implicit declaration of function 'ether_ntoa' is invalid in C99
    .xcodeprok cannot be opened because the project file cannot be parsed
    根据图片的链接获取图片的宽高
    关于UIWebView设置高度自适应的问题
    reason: 'data parameter is nil'
    CSS图标文字对齐和表单输入框文字对齐兼容
  • 原文地址:https://www.cnblogs.com/fenice/p/5701688.html
Copyright © 2011-2022 走看看