- 完全背包的变种,令dpjdpj表示取到第ii个数的容量为jj的背包(完全平方数之和),那么dpjdpj的最大值一定是jj本身(j∗1j∗1),那么从2≤i≤n2≤i≤n之间做完全背包,有状态转移方程:
dpj=min(dpj−i2+1,dpj)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; }