平方数
题目描述
珍珍在学习乘法时,发现4=22,9=33,…, 而2不可能分解为二个相同整数的乘积,但可以分解为11+11。她想知道对任意的整数n,把它分解为几个整数与自身相乘之和,有多少种方案呢?
输入
输入只有一行,该行只有一个正整数n。
输出
输出只有一行,该行只有一个正整数,表示总方案数。
样例
#1
输入
4
输出
2
#2
输入
13
输出
6
提示
【样例说明】
4有2种分解方案,它们是:4=1*1+1*1+1*1+1*1=2*2
13有6种分解方案,它们是:
13=1*1+1*1+1*1+1*1+1*1+1*1+1*1+1*1+1*1+1*1+1*1+1*1+1*1
=1*1+1*1+1*1+1*1+1*1+1*1+1*1+1*1+1*1+2*2
=1*1+1*1+1*1+1*1+1*1+2*2+2*2=1*1+1*1+1*1+1*1+3*3
=1*1+2*2+2*2+2*2=2*2+3*3
【数据限制】
20%的数据,1≤n≤10;
50%的数据,1≤n≤300;
80%的数据,1≤n≤800;
100%的数据,1≤n≤2000。
思路
本题是一道计算方案的动态规划题先设:
f[i][j]为前i个平方数加起来等于j的方案数
那么状态转移方程就应该为:
f[i][j] += f[i-1][j-i*i*k];
85分代码:
#include<bits/stdc++.h>
using namespace std;
int m,a[100],f[100][2020];
int main(){
for(int i=1;i<=80;i++){
a[i] = i*i;
}
cin >> m;
f[0][0] = 1;
for(int i=1;i<=80;i++){
for(int j=0;j<=m;j++){
for(int k=0;k*a[i]<=j;k++){
f[i][j] += f[i-1][j-a[i]*k];
}
}
}
cout << f[80][m] <<endl;
}
/**************************************************************
Language: C++
Result: 答案错误85
****************************************************************/
这个错误非常明显,那就是需要把f[i][j]设为long long的值要不最后三个样例会输出负数
AC code:
#include<bits/stdc++.h>
using namespace std;
long long m,f[100][2020];
int main(){
cin >> m;
f[0][0] = 1;
for(int i=1;i<=81;i++){
for(int j=0;j<=m;j++){
for(int k=0;k*i*i<=j;k++){
f[i][j] += f[i-1][j-i*i*k];
}
}
}
cout << f[80][m] <<endl;
}
/**************************************************************
Language: C++
Result: 正确100
Time:12 ms
Memory:3292 kb
****************************************************************/