[51nod1043]幸运号码

题意:1个长度为2N的数,如果左边N个数的和 = 右边N个数的和,那么就是一个幸运号码。

例如:99、1230、123312是幸运号码。

给出一个N,求长度为2N的幸运号码的数量。由于数量很大,输出数量 Mod 10^9 + 7的结果即可。

解题关键:

动态规划,dp[i][j]表示i个数和为j的总数(这里包括开头为0的情况)

$dp[i][j] = \sum\limits_{k = 0}^9 {dp[i - 1][j - k]} $
最后,我们只需要用去掉0打头的情况*没有去掉0打头的情况累加并取模即可。 
这里去掉0的方法是$dp[n][i] - dp[n - 1][i]$

这里可以进行滚动数组优化。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
ll dp[1002][9002];
int main(){
    int n;
    cin>>n;
    dp[0][0]=1;
    for(int i=1;i<=n;i++){
        for(int j=0;j<=9*i;j++){
            for(int k=0;k<=9&&k<=j;k++){
                dp[i][j]+=dp[i-1][j-k];
                dp[i][j]%=mod;
            }
        }
    }
    ll ans=0;
    for(int i=0;i<=9*n;i++){
        ans+=dp[n][i]*(dp[n][i]-dp[n-1][i]);
        ans%=mod;
    }
    cout<<ans<<"\n";
    return 0;
}
时间: 2024-10-08 07:54:02

[51nod1043]幸运号码的相关文章

51nod1043 幸运号码(数位dp)

1个长度为2N的数,如果左边N个数的和 = 右边N个数的和,那么就是一个幸运号码. 例如:99.1230.123312是幸运号码. 给出一个N,求长度为2N的幸运号码的数量.由于数量很大,输出数量 Mod 10^9 + 7的结果即可. Input 输入N(1<= N <= 1000) Output 输出幸运号码的数量 Mod 10^9 + 7 Input示例 1 Output示例 9 dp[i][j]  表示表示长度为2*i 其中一半的和为j的数量,当长度为i-1的已知时,计算长度为i时,无非

51nod 1043 幸运号码(数位dp)

题目链接:51nod 1043 幸运号码 题解:dp[i][j]表示 i 个数和为 j 的总数(包含0开头情况) dp[i][j] = dp[i-1][j-k] i & 1 :这里用滚动数组节省内存 非0开头的情况 * 0开头的情况:(dp[n&1][i]-dp[(n-1)&1][i]) *dp[n&1][i],最后将其累加即为结果. 1 #include<cstdio> 2 #include<algorithm> 3 #include<cst

AC日记——幸运号码 51nod 1043

幸运号码 思路: 传说中的数位dp: 不难发现,n(n<1000) ,那么,n个数的最大和为9*1000=9000: 对于9000*1000的时间范围,我们可以用dp来解决: dp[i][j],表示第i为数总和为j的号码的个数: 每个dp[i][j]都是dp[i-1][j-v](0<=v<=9) 的总和: 然后按照左边的n和右边的n,分为有前导0,和没有前导0进行dp: 然后输出排列的答案即可: dp[1000][9000]*2会爆空间,所以我选择压掉i维: 来,上代码: #includ

1043 幸运号码

1043 幸运号码 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 1个长度为2N的数,如果左边N个数的和 = 右边N个数的和,那么就是一个幸运号码. 例如:99.1230.123312是幸运号码. 给出一个N,求长度为2N的幸运号码的数量.由于数量很大,输出数量 Mod 10^9 + 7的结果即可. Input 输入N(1<= N <= 1000) Output 输出幸运号码的数量 Mod 10^9 + 7 Input示例 1 Output示例 9思路:dp.dp[i][j

51nod 1043 幸运号码(数位DP)

题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1043 题目: 1个长度为2N的数,如果左边N个数的和 = 右边N个数的和,那么就是一个幸运号码. 例如:99.1230.123312是幸运号码. 给出一个N,求长度为2N的幸运号码的数量.由于数量很大,输出数量 Mod 10^9 + 7的结果即可. Input 输入N(1<= N <= 1000) Output 输出幸运号码的数量 Mod 10^9 + 7

1043 幸运号码 数位DP

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1043 设dp[i][j]表示前i位数中,i位数的和为j时的所有情况. 转移的时候和普通的数位dp是一样转移的,但是如果你压缩了空间的话,就是用滚动数组的话,记录情况数就要多开一个变量来保存, 然后看看怎么排除前导0的情况. 如果产生的和值是j,然后前i - 1位产生的和值也是j,那么第i为就是前导0了.需要排除. 然后前n部分的和值的所有情况(需要排除前导0) * 后n

[bzoj1853][Scoi2010][幸运数字] (容斥原理)

Description 在中国,很多人都把6和8视为是幸运数字!lxhgww也这样认为,于是他定义自己的“幸运号码”是十进制表示中只包含数字6和8的那些号码,比如68,666,888都是“幸运号码”!但是这种“幸运号码”总是太少了,比如在[1,100]的区间内就只有6个(6,8,66,68,86,88),于是他又定义了一种“近似幸运号码”.lxhgww规定,凡是“幸运号码”的倍数都是“近似幸运号码”,当然,任何的“幸运号码”也都是“近似幸运号码”,比如12,16,666都是“近似幸运号码”. 现

[SCOI2010]幸运数字

题目背景 四川NOI省选2010 题目描述 在中国,很多人都把6和8视为是幸运数字!lxhgww也这样认为,于是他定义自己的“幸运号码”是十进制表示中只包含数字6和8的那些号码,比如68,666,888都是“幸运号码”!但是这种“幸运号码”总是太少了,比如在[1,100]的区间内就只有6个(6,8,66,68,86,88),于是他又定义了一种“近似幸运号码”.lxhgww规定,凡是“幸运号码”的倍数都是“近似幸运号码”,当然,任何的“幸运号码”也都是“近似幸运号码”,比如12,16,666都是“

1853: [Scoi2010]幸运数字[容斥原理]

1853: [Scoi2010]幸运数字 Time Limit: 2 Sec  Memory Limit: 64 MBSubmit: 2405  Solved: 887[Submit][Status][Discuss] Description 在中国,很多人都把6和8视为是幸运数字!lxhgww也这样认为,于是他定义自己的“幸运号码”是十进制表示中只包含数字6和8的那些号码,比如68,666,888都是“幸运号码”!但是这种“幸运号码”总是太少了,比如在[1,100]的区间内就只有6个(6,8,