Lucky Tickets URAL - 1036
原题链接
考察:数位dp+高精
思路:
数位dp太裸了,所以考察的是高精,参考大佬写了压位的高精,以后可以拿出来%.
转移的第三重循环不要从0~M,而是枚举这一位数字是什么.
Code
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 55,M = 555,Maxn = 10000;
typedef long long LL;
int n,s;
int f[N][M][N];
void add(int a[N],int b[N])
{
for(int i=0;i<N;i++)
a[i]+=b[i];
for(int i=0;i<N;i++)
a[i+1] += a[i]/Maxn,a[i]%=Maxn;
}
void mul(int a[N],int b[N])
{
static int c[M];
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
c[i+j] += a[i]*b[j];
for(int i=0;i<N;i++)
c[i+1] += c[i]/Maxn,c[i]%=Maxn;
int s = N-1;
while(s>0&&!c[s]) s--;
printf("%d",c[s]);
for(int i=s-1;i>=0;i--)
printf("%04d",c[i]);
printf("\n");
}
int main()
{
scanf("%d%d",&n,&s);
if(s%2) {puts("0");return 0;}
for(int i=0;i<10;i++) f[1][i][0] = 1;
for(int i=1;i<=n;i++)
for(int j=0;j<=s/2;j++)
for(int k=0;k<=9&&k<=j;k++)
add(f[i][j],f[i-1][j-k]);
mul(f[n][s/2],f[n][s/2]);
return 0;
}