您的位置:首页 > 其它

51nod 1043 幸运数字(数位dp)

2016-08-04 21:34 225 查看
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

用f[i][j]表示i个数的和为j的总数,这里面是包括0开头的情形,有f[i][j]=f[i-1]j-k。很好想,i个数组成总和为j的数量就来自于i-1个数 里面能 在最前面加0到9的数字使得加完之后和为j。

这里面包含了0开头的,把0去掉的方法就是f[i][j]-f[i-1][j]。f[i-1][j]就代表了在i个数中,开头为0的个数,减去就是i个数中开头不为0的个数。原因很明显,i个数和为j与i-1个数和为j,就差了一个位置为0。而这一个位置因为一开始咱们的想法就是在最前面加的数字,所以这个位置就差在了最前面的位置上。

然后这里因为递推只用到了前一项的结果,用i&1(相当于mod2)的方式存储两位就好了,节省下内存。

#include<cstring>
#include<string>
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<queue>
#include<vector>
#include<map>
#include<stack>
#include<climits>
#include<cctype>
#include<bitset>
#include<set>
using namespace std;
#define mod 1000000007
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
typedef long long LL;

const int MAX=1005;
LL f[2][MAX*9];

int main()
{
int n;
memset(f,0,sizeof(f));
cin>>n;
f[0][1]=1;//为了1特判
for(int i=0;i<10;i++)
f[1][i]=1;
for(int i=2;i<=n;i++){
for(int j=0;j<=i*9;j++){
LL sum=0;
for(int k=0;k<10;k++){
if(j>=k)
sum=(sum+f[(i-1)&1][j-k])%mod;
}
f[i&1][j]=sum;
}
}
LL ans=0;
for(int i=0;i<=n*9;i++){
ans=(ans+f[n&1][i]*(f[n&1][i]-f[(n-1)&1][i]))%mod;
}
cout<<ans<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  dp