https://www.acmicpc.net/problem/17626
17626번: Four Squares
라그랑주는 1770년에 모든 자연수는 넷 혹은 그 이하의 제곱수의 합으로 표현할 수 있다고 증명하였다. 어떤 자연수는 복수의 방법으로 표현된다. 예를 들면, 26은 52과 12의 합이다; 또한 42 + 32 + 1
www.acmicpc.net
문제 풀이
그 전에 풀었던 문제가 그리디 문제여서 이번 문제도 별 생각 없이 그리디로 접근했다가 예제는 잘 나왔는데 틀렸다.
제곱수들의 배열을 만들고 n보다 작고, 가장 가까운 제곱수를 만나면 빼고 다시 n보다 작고, 가장 가까운 제곱수 찾아서~~ 이런식으로 구현했다.
이 경우 n = 21841이면 21841 = 104 ^ 2 + 105 ^ 2이 최적인데 나는 147 * 147 = 21609라 그리디는 최적의 경우를 보장하지 않더라...
결론적으로 DP를 이용해 문제를 해결했다.
num[n] = min(num[n] , num[n-1^2) +1, num[n-2^2] +1 ...) 이런식으로 구현했다.
소스 코드
#include <iostream>
using namespace std;
int square_num[50001] = { 0 };
int main() {
int n;
cin >> n;
// 초기화
for (int i = 0; i <= n; i++) {
square_num[i] = 99999999;
}
for (int i = 0; i * i <= n; i++) {
square_num[i * i] = 1;
}
//dp를 이용한 최소횟수 구하기
for (int i = 2; i <= n; i++) {
for (int j = 1; i - j * j >= 0; j++) {
square_num[i] = min(square_num[i], square_num[i - j * j] + 1);
}
}
cout << square_num[n] << '\n';
}
'알고리즘' 카테고리의 다른 글
[백준] 14754번 Pizza Boxes C++ 문제풀이 (1) | 2023.10.16 |
---|---|
[백준] 14753번 MultiMax C++ 문제풀이 (0) | 2023.10.16 |
[백준] 17521번 Byte Coin C++ 문제풀이 (0) | 2023.10.13 |
[백준] 16283번 FARM C++ 문제풀이 (1) | 2023.10.12 |
[백준] 20040번 사이클 게임 C++ 문제풀이 (0) | 2023.10.05 |