题目链接:
Description
佳佳碰到了一个难题,请你来帮忙解决。
对于不定方程 (a1+a2+⋯+ak−1+ak=g(x)),其中 (k≥1) 且 (k∈N∗),(x) 是正整数,(g(x)=x^xmod1000)(即 x 除以 1000 的余数),(x,k) 是给定的数。
我们要求的是这个不定方程的正整数解组数。
举例来说,当 (k=3,x=2) 时,方程的解分别为:
(1:a_1=1,a_2=1,a_3=2;)
(2:a_1=1,a_2=2,a_3=1;)
(3:a_1=2,a_2=1,a_3=1;)
Input
有且只有一行,为用空格隔开的两个正整数,依次为 (k,x)。
(1≤k≤100,)
(1≤x<231,)
(k≤g(x))
Output
有且只有一行,为方程的正整数解组数。
Sample Input
3 2
Sample Output
3
题意
求k个大于0的数凑成(x^x%1000)的方案数之和
题解:
隔板法求解等式:(a1+a2+⋯+ak−1+ak=n)。可以用快速幂求出(n=x^x%1000)。我们把n想象成n个水平排列的小球,我们需要把这些小球用挡板分成k部分,每一部分都大于0。
(eg:n=8,k=4),我们可以在n-1个空隙中选择k-1插入挡板,第i个挡板的前面的小球数对应(a_i),第k-1个挡板后面的球数等于(a_k)
代码
#include<bits/stdc++.h>
using namespace std;
int qmi(int a,int b){
int res=1;
while(b){
if(b&1) res=1ll*res*a%1000;
b>>=1;
a=1ll*a*a%1000;
}
return res;
}
int f[1010][101][200];
void add(int a[],int b[],int c[]){
for(int i=0;i<199;++i){
a[i]+=b[i]+c[i];
a[i+1]+=(a[i])/10;
a[i]%=10;
}
}
int main(){
int k,x;
cin>>k>>x;
x=qmi(x,x);
if(x==0){
cout<<0<<endl;
return 0;
}
for(int i=0;i<=x;++i){
for(int j=0;j<k&&j<=i;++j)
if(!j)f[i][j][0]=1;
else add(f[i][j],f[i-1][j-1],f[i-1][j]);
}
int i=199;
while(f[x-1][k-1][i]==0&&i!=0) --i;
while(i>=0) cout<<f[x-1][k-1][i--];
return 0;
}