持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第4天,点击查看活动详情
【动态规划】 洛谷 P1586 四方定理
题目描述
四方定理是众所周知的:任意一个正整数n,可以分解为不超过四个整数的平方和。例如:,当然还有其他的分解方案,。给定的正整数n,编程统计它能分解的方案总数。注意:视为一种方案。
输入格式
第一行为正整数,接下来t行,每行一个正整数。
输出格式
对于每个正整数n,输出方案总数。
样例 #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[i][j]的第二维就是平方数的个数,在解决了方案总数怎么求之后,就要考虑只能用四个或四个以下。所以要加一维。
总结为fj代表价值上线为j,取k个数作组合时的方案总数。则最后答案为f[n][1]到f[n][4]的和。
#include<bits/stdc++.h>
using namespace std;
int a[200],f[32775][10],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;
}