Algorithm/BOJ
[BOJ/C++]1699번 제곱수의 합
DEV Lee
2020. 8. 18. 01:26
https://www.acmicpc.net/problem/1699
1699번: 제곱수의 합
어떤 자연수 N은 그보다 작거나 같은 제곱수들의 합으로 나타낼 수 있다. 예를 들어 11=32+12+12(3개 항)이다. 이런 표현방법은 여러 가지가 될 수 있는데, 11의 경우 11=22+22+12+12+12(5개 항)도 가능하다
www.acmicpc.net
문제
자연수 n을 $11=2^2+2^2+1^2+1^2+1^2$ 혹은 $11=3^2+1^2+1^2$와 같은 제곱수들의 합으로 나타낼 수 있다. 이때 표현할 수 있는 제곱수 항의 최소 개수를 구해라.
풀이
i가 제곱수로 표현가능한 경우, 즉 i=j*j인 경우는 dp[i]가 1이다.
그 경우 dp[i]에 1을 넣어주고, 그 외에 경우에는 일단 dp[i]=dp[i-1]+1을 해 준다(직전 경우에 $1^2$를 더한 경우의 수)
그리고 j가 1부터 $j^2$가 i보다 작을 때 까지 i를 늘려주며 dp[i-$j^2$]+$j^2$를 한 경우가 현재의 dp[i]값보다 작은지 비교하며 dp[i]값을 정한다.
소스코드
#include<iostream>
#include<cmath>
using namespace std;
int main(void){
int n;
cin>>n;
int dp[n+1];
dp[1]=1;
for(int i=2;i<=n;i++){
dp[i]=dp[i-1]+1;
if(0==sqrt(i)-(int)sqrt(i)){
dp[i]=1;
continue;
}
for(int j=1;j*j<i;j++){
dp[i]=min(dp[i],dp[i-j*j]+1);
}
}
cout<<dp[n]<<endl;
}