您的位置:首页 > 其它

51Nod 1043 幸运号码 数位DP

2017-10-15 14:01 316 查看
1043 幸运号码
 

基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题


 收藏


 关注

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] 代表i位数的和为j的方案数
一位数 xxxt 可以看做是在一个三位数后面添加一个数t 
明显 dp[i][j] + = dp[i-1][j-t];
转移 就是dp[i][j]=Σdp[i-1][j-t] (j-t>=0) 
统计ans要注意 
每次我们都是在一个数后面加一个数t(t>=0&&t<=9) 
所以我们可能出现 左边数的第一位我们放了0的情况 
左边的一个数的第一位不可能为0 所以要减去第一位为0的情况
 





1 #include <cctype>
2 #include <cstdio>
3
4 typedef long long LL;
5 const int mod=1e9+7;
6 const int MAXN=1010;
7
8 int n,m;
9
10 LL ans;
11
12 LL dp[2][MAXN*10];
13
14 int hh() {
15     scanf("%d",&n);
16     dp[0][0]=1;
17     for(int i=1;i<=n;++i)
18       for(int j=0;j<=n*9;++j) {
19           dp[i&1][j]=0;
20             for(int t=0;t<=9;++t) {
21               if(j-t<0) continue;
22               dp[i&1][j]=(dp[i&1][j]+dp[(i-1)&1][j-t])%mod;
23           }
24       }
25     for(int i=0;i<=n*9;++i)
26       ans=(ans+dp[n&1][i]*(dp[n&1][i]-dp[(n-1)&1][i]))%mod;
27     printf("%lld\n",ans);
28     return 0;
29 }
30
31 int sb=hh();
32 int main(int argc,char**argv) {;}


代码
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: