幸运票
题目大意:
一个长度为2N的序列,这些数的总和为S,当这个序列的前N个和后N个总和相等时,它是符合题意的,问有符合题意的有多少种可能
样例输入
2 2
样例输出
4
数据范围限制
1<=N<=50
S<=1000
解题思路:
先将S/2得出两边的总数分别是多少,然后再用DP枚举每一位数和总和,在经过特判,用每一位往后推
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int n,s,f[52][1002][102],c[202];
void gzj(int x,int y,int l)
{
for (int i=1;i<=100;i++)
{
f[x][y][i]+=f[x-1][y-l][i];
f[x][y][i+1]+=f[x][y][i]/10;
f[x][y][i]%=10;
}
}
void gzc()
{
for (int i=1;i<=100;i++)
for (int j=1;j<=100;j++)
{
c[i+j-1]+=f[n][s][i]*f[n][s][j];
c[i+j]+=c[i+j-1]/10;
c[i+j-1]%=10;
}
}
int main()
{
freopen("tickets.in","r",stdin);
freopen("tickets.out","w",stdout);
scanf("%d %d",&n,&s);
s/=2;
for (int i=1;i<=n;i++)
for (int j=0;j<=s;j++)
if (j>i*9) continue;
else if (i==1&&j<=9) f[i][j][1]=1;
else for (int k=0;k<=min(j,9);k++) gzj(i,j,k);
gzc();
int p=200;
while (!c[p]&&p) p--;
if (!p) printf("0");
for (int i=p;i>=1;i--)
printf("%d",c[i]);
fclose(stdin);
fclose(stdout);
return 0;
}