일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 문자열
- BFS
- 너비 우선 탐색
- 자바스크립트
- 가끔은 말로
- pytorch
- DP
- 크루스칼
- 분할 정복
- Overfitting
- 백트래킹
- 다익스트라
- 우선 순위 큐
- dfs
- 알고리즘
- 회고록
- tensorflow
- dropout
- 세그먼트 트리
- NEXT
- back propagation
- 2023
- c++
- 미래는_현재와_과거로
- 이분 탐색
- lazy propagation
- object detection
- 플로이드 와샬
- 조합론
- 가끔은_말로
Archives
- Today
- Total
Doby's Lab
[알고리즘] 백준 4150번: 피보나치 수 (C++), DP인데 배열을 안 쓴다고? 본문
https://www.acmicpc.net/problem/4150
4150번: 피보나치 수
피보나치 수열은 다음과 같이 그 전 두 항의 합으로 계산되는 수열이다. 첫 두 항은 1로 정의된다. f(1) = 1, f(2) = 1, f(n > 2) = f(n − 1) + f(n − 2) 정수를 입력받아, 그에 해당하는 피보나치 수를 출력
www.acmicpc.net
이 문제는 저번에 풀었던 문제와 똑같다고 생각했다. (https://www.acmicpc.net/problem/10826)
당연히 포인트도 똑같이 수를 문자열로 바꾸어 합을 구하는 함수를 구현하는 게 포인트라고 생각했다.
똑같은 풀이를 제출했으나 '메모리 초과'라는 오류를 받는다.
메모리가 크게 발생할 곳은 배열 밖에 없다고 생각했지만 배열을 안 쓰고서 구현할 수 있을까 생각했다.
[솔루션에 도출하기까지의 아이디어]
1. 어차피 원하는 건 result
2. 점화식에 필요한 건 2개의 fibo(n - 1), fibo(n - 2)
3. 변수 2개로 해결할 수는 없을까?
>> 합이 나올 때마다 result에 넣고, 한 번 더 합을 진행해야 한다면 기존 2번 변수를 1번 변수, result 값을 2번 변수에 넣으면 되겠다는 생각이 들었다.
>>>> swap에서 영감받음
[Before]
cache[1] = "1";
cache[2] = "1";
for (int i = 3; i <= n; i++) {
cache[i] = strSum(cache[i - 1], cache[i - 2]);
}
[After]
if (n == 0) {
result = "0";
}
if (n == 1) {
result = "1";
}
for (int i = 2; i <= n; i++) {
result = strSum(value1, value2);
value1 = value2;
value2 = result;
}
[전체 소스 코드]
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
int n;
string strSum(string a, string b) {
reverse(a.begin(), a.end());
reverse(b.begin(), b.end());
while (a.length() > b.length()) {
b += '0';
}
while (a.length() < b.length()) {
a += '0';
}
int alone;
int carry = 0;
string result;
for (int i = 0; i < a.length(); i++) {
alone = ((a[i] - '0') + (b[i] - '0') + carry) % 10;
result += to_string(alone);
carry = ((a[i] - '0') + (b[i] - '0') + carry) / 10;
}
if (carry > 0) {
result += to_string(carry);
}
reverse(result.begin(), result.end());
return result;
}
int main() {
cin >> n;
vector<string> cache(n + 1);
string value1 = "0";
string value2 = "1";
string result;
if (n == 0) {
result = "0";
}
if (n == 1) {
result = "1";
}
for (int i = 2; i <= n; i++) {
result = strSum(value1, value2);
value1 = value2;
value2 = result;
}
cout << result;
return 0;
}
오랜만에 기존 지식의 틀을 깨는 문제였다. 예전엔 이런 문제 싫었는데 이제는 틀을 넓히는 느낌이라 좋다!
728x90
'PS > BOJ' 카테고리의 다른 글
[알고리즘] 백준 1541번: 잃어버린 괄호 (C++), 경험으로부터 나온 생각과 내 거친 생각과 불안ㅎ.. (0) | 2021.11.09 |
---|---|
[알고리즘] 백준 9663번: N-Queen, Backtracking의 대표 문제 (0) | 2021.11.08 |
[자료구조] 백준 5525번: IOIOI (C++), 스택을 이용한 트릭 (0) | 2021.11.05 |
[알고리즘] 백준 1254번: 팰린드롬 만들기 (C++), 같은 실수 반복하지 않기 (0) | 2021.11.05 |
[알고리즘] 백준 2792번: 보석 상자 (C++), 최솟값과 최댓값의 활용 (0) | 2021.11.03 |