Notice
Recent Posts
Recent Comments
Link
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
Archives
Today
Total
관리 메뉴

알고리즘 공부방

백준 1699 제곱수의 합(C++) 본문

카테고리 없음

백준 1699 제곱수의 합(C++)

head89 2023. 1. 5. 02:41

https://www.acmicpc.net/problem/1699

 

1699번: 제곱수의 합

어떤 자연수 N은 그보다 작거나 같은 제곱수들의 합으로 나타낼 수 있다. 예를 들어 11=32+12+12(3개 항)이다. 이런 표현방법은 여러 가지가 될 수 있는데, 11의 경우 11=22+22+12+12+12(5개 항)도 가능하다

www.acmicpc.net

 

문제 유형: DP, Math

 

 

문제 풀이

생각을 했을 때 n이 주어지면, (n - n보다 작은 수 중 가장 큰 제곱 수)의 dp값에서 +1을 해주는 것이 정답이라 생각했다.

그러다 충분히 반례가 존재할거라 생각하여, (n - n보다 작은 수 중 제곱수인 수)의 dp값 + 1 중 가장 작은 것이 정답이라 

생각했다.

1부터 n까지 바텀업 방식으로 dp를 돌린다.

즉, i보다 작은 제곱수를 i에서 뺀 값의 dp에 +1의 가장 작은 값이 dp[i]가 된다.

수식으로 적어보면

dp[i] = min(dp[i - n * n] + 1, dp[i]) 이렇게 된다.

 

전체 코드

#include <iostream>
using namespace std;
int dp[100001];
int main(void)
{
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);

    int n; cin >> n;

    for(int i = 1;i<=n;i++){
        dp[i] = i;
        for(int j = 1;j*j <=i;j++){
            dp[i] = min(dp[i], dp[i-j*j] + 1);
        }
    }
    cout<<dp[n];
    return 0;
}