P1586 四方定理
题意:题意很简单。
解法:听说这题能四重循环+剪枝过,时间复杂度得卡一卡,正解是dp,dp大法好 ,用递推考虑,dp[j][k]表示j用k个平方数表示的方案数,转移方程就是
d
p
[
j
]
[
k
]
=
∑
d
p
[
j
−
i
∗
i
]
[
k
−
1
]
dp[j][k]=\sum dp[j-i*i][k-1]
dp[j][k]=∑dp[j−i∗i][k−1],正序也有用到完全背包的思想,背包九讲(手动滑稽)。
代码:
#include<bits/stdc++.h>
using namespace std;
const int N = 32768;
const int M = 4e4+10;
const int Mod = 1e9+7;
int dp[M][5];
int main() {
int t, n;
dp[0][0] = 1;
for(int i = 1; i*i <= N; ++i) { //枚举平方数
for(int j = i*i; j <= N; ++j) { //递推!!!
for(int k = 1; k <= 4; ++k) { //表示选取了多少个平方数
dp[j][k] += dp[j-i*i][k-1];
}
}
}
scanf("%d", &t);
while(t--) {
scanf("%d", &n);
int ans = 0;
for(int i = 1; i <= 4; ++i) {
ans += dp[n][i];
}
printf("%d\n", ans);
}
return 0;
}