You are given a number 1 ≤
N ≤ 50. Every ticket has its 2
N-digit number. We call a ticket lucky, if the sum of its first
N digits is equal to the sum of its last
N digits. You are also given the sum of ALL digits in the number. Your task is to count an amount of lucky numbers, having the specified sum of ALL digits.
Input
Two space-separated numbers:
N and
S. Here
S is the sum of all digits. Assume that 0 ≤
S ≤ 1000.
Output
The amount of lucky tickets.
Sample
input | output |
---|---|
2 2 | 4 |
Hint
The tickets are 0101, 0110, 1001, 1010 in the example above
一开始DP公式推错了(dp(i,j)=dp(i-1,j)+dp(i,j-1)),和之前ZOJ3216有点象,但是有很大的区别:这道题是10进制,每一位的大小只能取0-9而那一题能取0-n;
最终的DP公式为dp(i,j) = dp(i,j)+dp(i-1,j-k)0<=k<=9 i为数字的位数 j为和的大小
这样就结束了吗???高精度啊!!!!!!
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
#include <string>
#include <queue>
using namespace std;
const int maxn = 100+10;
const int ten[4] = {1,10,100,1000};
struct BigNum{
int d[maxn];
BigNum(string s){
int len =s.size();
d[0] = (len-1)/4+1;
int i,j,k;
for(i = 1; i < maxn; i++) d[i] = 0;
for(i = len-1;i>=0;i--){
j = (len-1-i)/4+1;
k = (len-1-i)%4;
d[j]+=ten[k]*(s[i]-'0');
}
while(d[0]>1&&d[d[0]]==0) --d[0];
}
BigNum(){
*this = BigNum(string("0"));
}
string toString(){
string s("");
int i,j,tmp;
for( i = 3; i >= 1; i--) if(d[d[0]]>=ten[i]) break;
tmp = d[d[0]];
for(j = i; j>=0; j--){
s=s+(char)(tmp/ten[j]+'0');
tmp%=ten[j];
}
for(i = d[0]-1; i>0; i--){
tmp = d[i];
for(j = 3; j >=0 ;j--){
s = s+(char)(tmp/ten[j]+'0');
tmp%=ten[j];
}
}
return s;
}
};
BigNum operator + (BigNum a,BigNum b){
BigNum c;
c.d[0] = max(a.d[0],b.d[0]);
int x=0;
for(int i = 1; i <= c.d[0]; i++){
x = a.d[i]+b.d[i]+x;
c.d[i] = x%10000;
x/=10000;
}
while(x!=0){
c.d[++c.d[0]]=x%10000;
x/=10000;
}
return c;
}
BigNum operator * (BigNum a,BigNum b){
BigNum c;
c.d[0] = a.d[0]+b.d[0];
for(int i = 1; i<= a.d[0]; i++){
int x = 0;
for(int j = 1; j <= b.d[0]; j++){
x = a.d[i]*b.d[j]+x+c.d[i+j-1];
c.d[i+j-1]=x%10000;
x/=10000;
}
c.d[i+b.d[0]]=x;
}
while((c.d[0]>1)&&(c.d[c.d[0]]==0)) --c.d[0];
return c;
}
BigNum dp[60][1010];
int n,s;
void init(){
for(int i = 0; i <= n; i++)
for(int j = 0; j<= s; j++){
dp[i][j] = BigNum("0");
}
}
int main(){
while(~scanf("%d%d",&n,&s)){
if(s&1){
cout<<0<<endl;
continue;
}
else if(s>18*n){
cout<<0<<endl;
continue;
}
init();
s/=2;
for(int i = 0; i <= s; i++){
if(i>9)
dp[1][i] = BigNum("0");
else
dp[1][i] = BigNum("1");
}
for(int i = 0; i <= n; i++){
dp[i][0] = BigNum("1");
dp[0][i] = BigNum("0");
}
for(int i = 1; i <= n; i++){
for(int j = 1; j <= s; j++){
for(int k = 0; k <=9; k++){
if(j>=k){
dp[i][j] = dp[i-1][j-k]+dp[i][j];
}
}
}
}
BigNum ans = dp[n][s];
ans = ans*ans;
cout<<ans.toString()<<endl;
}
return 0;
}