完全背包 DP:dp[i] 从所有不超过 i 的平方数转移,取最小值。
OJ: leetcodecn
题目 ID: perfect-squares
难度:普及/提高-
标签:动态规划完全背包
日期: 2026-07-29 12:37
题意
求和为 n 的完全平方数的最少个数。
思路
dp[i] 表示和为 i 的最少完全平方数个数。dp[i] = min(dp[i - j*j] + 1) 对所有 j*j <= i。初值 dp[0] = 0,其余 INF。
代码
cpp
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
int numSquares(int n) {
vector<int> dp(n + 1, INT_MAX / 2);
dp[0] = 0;
for (int i = 1; i <= n; i++)
for (int j = 1; j * j <= i; j++)
dp[i] = min(dp[i], dp[i - j * j] + 1);
return dp[n];
}
};
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
cout << Solution().numSquares(n) << '\n';
return 0;
}python
#!/usr/bin/env python3
class Solution:
def numSquares(self, n: int) -> int:
dp = [float("inf")] * (n + 1)
dp[0] = 0
for i in range(1, n + 1):
j = 1
while j * j <= i:
dp[i] = min(dp[i], dp[i - j * j] + 1)
j += 1
return dp[n]
def main():
print(Solution().numSquares(int(input())))
if __name__ == "__main__":
main()复杂度
- 时间复杂度:
。 - 空间复杂度:
。
总结
完全平方数是完全背包的变形:物品是所有平方数,每个可无限使用,求凑满目标的最少物品数。