此题使用DP。设f[i][j]表示数i用j个数表示,则对于所有的k<=sqrt(i),有
f[i][j]=∑f[i-k*k][j-1]
但是这样会有重复情况。所以先枚举k,再枚举i和j。
代码如下
#include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<cctype> inline long long read(){ long long num=0,f=1; char ch=getchar(); while(!isdigit(ch)){ if(ch=='-') f=-1; ch=getchar(); } while(isdigit(ch)){ num=num*10+ch-'0'; ch=getchar(); } return num*f; } long long f[35000][10]={1}; int main(){ int T=read(); for(int k=1;k*k<=35000;++k) for(int i=k*k;i<=35000;++i) for(int j=1;j<=4;++j) f[i][j]+=f[i-k*k][j-1]; while(T--){ int n=read(); printf("%lld ",f[n][1]+f[n][2]+f[n][3]+f[n][4]); } return 0; }