解题思路:
- 完全背包的变种,令dpj表示取到第i个数的容量为j的背包(完全平方数之和),那么dpj的最大值一定是j本身(j∗1),那么从2≤i≤n之间做完全背包,有状态转移方程:
dpj=min(dpj−i2+1,dpj)
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
cin>>n;
vector<int> dp(n+1);
for(int i = 1; i <= n; ++i){
dp[i] = i;
}
for(int i = 2; i <= (int)sqrt(n); ++i){
for(int j = 0; j <= n-i*i; ++j){
dp[j+i*i] = min(dp[j+i*i],dp[j]+1);
}
}
cout<<dp[n]<<endl;
return 0;
}