也可以在 LuoguP1586 (tencentcs.com) 获得更好的阅读体验。
Luogu_P1586 题解
一道比较简单的题目,看到求种类数,考虑 DP。
设 \(f_{i,j}\) 表示第 \(i\) 个数划分为 \(j\) 个数的平方的种类数,那么很显然的,当你从 \(i\) 中划出一个平方数 \(k^2\),那么问题相当于变成了 如何将 \(i-k^2\) 划分为 \(j-1\) 个数,于是状态转移方程就呼之欲出了:\(f_{i,j}=\sum\limits_{k=1}^{k^2\le i}f_{i-k^2,j-1}\)。
这个玩意的转移只能按照 \(k,i,j\) 的顺序枚举,不然会重复统计/漏统计一些数。边界条件很显然的是 \(f_{0,0}=1\),因为此时我们的目标已经达成了。
多测注意清空。
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
#define lson (p << 1)
#define rson ((p << 1) | 1)
#define mid ((l + r) >> 1)
const int MAXN = 50005;
int n, f[MAXN][5], T, ret;
signed main(void) {
ios::sync_with_stdio(false);
cin.tie(0);
f[0][0] = 1;
for (int i = 1; i * i <= 32768; ++i) {
for (int j = i * i; j <= 32768; ++j) {
for (int k = 1; k <= 4; ++k) f[j][k] += f[j - i * i][k - 1];
}
}
cin >> T;
while (T--) {
cin >> n;
for (int i = 1; i <= 4; ++i) ret += f[n][i];
cout << ret << endl; ret = 0;
}
return 0;
}
标签:int,题解,个数,long,LuoguP1586,define
From: https://www.cnblogs.com/XiaoQuQu/p/16875272.html