728x90
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에 대해서 가장 적은 제곱수의 합은 무엇이 있을까?
N-(1*1)에서 1*1가 더해진 경우
N-(2*2)에서 2*2가 더해진 경우
N-(3*3)에서 3*3가 더해진 경우
이런식으로 N-(j*j)가 0일때까지의 경우가 있을 것이다.
우리는 가장 적은 항으로 표현한 제곱수 합을 구해야한다.
따라서, 다음과 같이 표현할 수 있다.
for (int i = 3; i <= n; i++) {
for (int j = 1; j * j <= i; j++) {
dp[i] = min(dp[i], dp[i - j * j] + 1);
}
}
이런식으로만 코딩을 하면 0이 도출된다.
왜냐하면, 전역변수로 선언해서 기본값이 0으로 설정되어있기때문이다.
그렇기 때문에, 기본값을 초기화해야한다.
어떤 값으로 초기화해야할까?
가장 많은 항의 개수로 초기화하면된다.
가장 많은 항이 되려면 무조건 1로만 이루어져야 하기 때문에
DP[i] = i로 초기화하면된다.
코드
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <cmath>
#define MAX 100001
using namespace std;
int n,t;
int dp[MAX];
void init() {
for (int i = 1; i <= n; i++)
dp[i] = i;
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n;
init();
for (int i = 3; i <= n; i++) {
for (int j = 1; j * j <= i; j++) {
dp[i] = min(dp[i], dp[i - j * j]+1);
}
}
cout << dp[n];
}
728x90
'📊알고리즘 > BOJ' 카테고리의 다른 글
[DP #17] (BOJ 15486) 퇴사 2 (0) | 2023.08.29 |
---|---|
[👊DP뿌시기 #13-2] (BOJ 2293) 동전 2 (0) | 2023.08.28 |
[👊DP뿌시기 #15] (BOJ 15988) 1, 2, 3, 더하기 3 (0) | 2023.08.28 |
[👊DP뿌시기 #14] (BOJ 11057) 오르막 수 (0) | 2023.08.27 |
[👊DP뿌시기 #13] (BOJ 2293) 동전 1 (0) | 2023.08.26 |