携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第7天,点击查看活动详情
四方定理
题目描述
四方定理是众所周知的:任意一个正整数,可以分解为不超过四个整数的平方和。例如:,当然还有其他的分解方案,和。给定的正整数,编程统计它能分解的方案总数。注意:和视为一种方案。
输入格式
第一行为正整数(),接下来行,每行一个正整数()。
输出格式
对于每个正整数,输出方案总数。
样例 #1
样例输入 #1
1
2003
样例输出 #1
48
解题思路
就是一个背包,把每个平方数看成一个物品,求方案数。 因为对用的数的个数有要求,所以是二维费用背包,要注意的是每个数是不限个数的。
先构造a[i],就是平方数,这是物品大小,n就是背包大小,设f[i]表示背包大小为i能装满的方案
核心如下:
for (int i=1;i<=物品总数;i++)
for (int j=a[i];j<=背包最高价值;j++)
f[j]+=f[j-a[i]];
f[][]的第二维就是平方数的个数,在解决了方案总数怎么求之后,就要考虑只能用四个或四个以下。所以要加一维。
总结为f[j][k]代表价值上线为j,取k个数作组合时的方案总数。则最后答案为f[n][1]到f[n][4]的和。
#include<bits/stdc++.h>
using namespace std;
int a[185],f[32770][5],m,n;
int main()
{ for(int i=1;i<=181;i++)
a[i]=i*i;
f[0][0]=1;
for (int i=1;i<=181;i++)
for (int j=a[i];j<=32768;j++)
for(int k=1;k<=4;k++)
f[j][k]+=f[j-a[i]][k-1];
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>m;
cout<<f[m][1]+f[m][2]+f[m][3]+f[m][4]<<endl;
}
return 0;
}