티스토리 뷰
https://www.acmicpc.net/problem/2748
2748번: 피보나치 수 2
피보나치 수는 0과 1로 시작한다. 0번째 피보나치 수는 0이고, 1번째 피보나치 수는 1이다. 그 다음 2번째 부터는 바로 앞 두 피보나치 수의 합이 된다. 이를 식으로 써보면 Fn = Fn-1 + Fn-2 (n ≥ 2)가
www.acmicpc.net
🤔 해결방법
1. dp 배열 초기화
2. 0번째, 1번째 수 0, 1로 지정
3. i번째 = i-2번째 + i-1번째라는 규칙으로 for문 작성
이 때, BigInt 사용
4. 마지막 출력에서 toString사용
🔑 풀이
const input = require("fs")
// .readFileSync("/dev/stdin")
.readFileSync(__dirname + "/input.txt")
.toString()
.trim()
.split("\n");
const n = Number(input[0]);
function solution(n) {
const dp = new Array(n + 1).fill(0);
dp[0] = 0;
dp[1] = 1;
for (let i = 2; i < n + 1; i++) {
dp[i] = BigInt(dp[i - 2]) + BigInt(dp[i - 1]);
}
return dp[n].toString();
}
console.log(solution(n));
피보나치 수는 i번째 = i-2번째 + i-1번째 라는 규칙을 가지고 있다.
그런데 예를들어 90번째 피보나치 수는 '2,880,067,194,370,816,000'의 엄청 큰 수이다.
javascript에 존재하는 한계점으로 인해 정확한 수를 표시할 수 없기 때문에 BigInt 객체 형식으로 바꾸어 피보나치 수를 계산해야 했다.
BigInt는 Number 원시 값이 안정적으로 나타낼 수 있는 최대치인 2^53 - 1보다 큰 정수를 표현할 수 있는 내장 객체이다.
마지막 출력 단계에서 BigInt의 값을 진수로 표현시켜주는 내장 toString 메서드 사용해줘야 한다.
https://www.acmicpc.net/problem/2749
2748번: 피보나치 수 2
피보나치 수는 0과 1로 시작한다. 0번째 피보나치 수는 0이고, 1번째 피보나치 수는 1이다. 그 다음 2번째 부터는 바로 앞 두 피보나치 수의 합이 된다. 이를 식으로 써보면 Fn = Fn-1 + Fn-2 (n ≥ 2)가
www.acmicpc.net
🤔 해결방법
1. 피사노 주기로 dp 배열 초기화
2. 0번째, 1번째 수 BigInt(0), BigInt(1)로 지정
3. i번째 = (i-2번째 + i-1번째) % BigInt(1000000) 라는 규칙으로 for문 작성
4. 마지막 출력에서 toString사용
🔑 풀이
const input = require("fs")
// .readFileSync("/dev/stdin")
.readFileSync(__dirname + "/input.txt")
.toString()
.trim()
.split("\n");
const n = BigInt(input[0]);
// 피사노 주기
const pisano = 1500000;
const mod = n % BigInt(pisano);
function solution(n) {
const dp = new Array(pisano).fill(BigInt(0));
dp[0] = BigInt(0);
dp[1] = BigInt(1);
for (let i = 2; i <= n; i++) {
dp[i] = (dp[i - 2] + dp[i - 1]) % BigInt(1000000);
}
return dp[n];
}
console.log(solution(mod).toString());
피보나치 수열에서 특정 수로 나눈 나머지는 주기를 가지는데, 이를 피사노 주기라 한다.
피사노 주기는 모듈로 연산의 피연산자가 10^k일 때, 피사노 주기는 15*10^(k-1)이 된다.
따라서 1000000으로 나눈 나머지이기 때문에 k가 6이되므로 피사노 주기는 15*10^(6-1) = 1500000이다.
https://www.acmicpc.net/problem/9461
9461번: 파도반 수열
오른쪽 그림과 같이 삼각형이 나선 모양으로 놓여져 있다. 첫 삼각형은 정삼각형으로 변의 길이는 1이다. 그 다음에는 다음과 같은 과정으로 정삼각형을 계속 추가한다. 나선에서 가장 긴 변의
www.acmicpc.net
🤔 해결방법
1. dp 배열 초기화
2. 0번째, 1번째, 2번째 수를 0, 1, 1로 지정
3. i번째 = i-2번째 + i-3번째 라는 규칙으로 for문 작성
4. n번째 요소 출력
🔑 풀이
const input = require("fs")
// .readFileSync("/dev/stdin")
.readFileSync(__dirname + "/input.txt")
.toString()
.trim()
.split("\n");
const t = Number(input[0]);
let number = []; // 테스트케이스 담는 배열
for (let i = 1; i <= t; i++) {
number.push(Number(input[i]));
}
// 1, 1, 1, 2, 2, 3, 4, 5, 7, 9 => i번째 = i-2번째 + i-3번째
function solution(n) {
const dp = new Array(n + 1).fill(0);
dp[0] = 0;
dp[1] = dp[2] = 1;
for (let i = 3; i < n + 1; i++) {
dp[i] = dp[i - 2] + dp[i - 3];
}
return dp[n];
}
number.forEach((e) => console.log(solution(e))); // 테스트케이스 하나씩 넣어주고 값 출력
규칙찾아서 점화식만 세우니 쉽게 풀 수 있었다.
dp 문제는 이 정도 수준의 문제만 나왔으면 좋겠다.. 😂
'JS-algorithm > BOJ' 카테고리의 다른 글
[백준] 계단 오르기, 포도주 시식, RGB거리 (javascript) (0) | 2024.01.27 |
---|---|
[백준] 꿀 아르바이트, 블로그, DNA 비밀번호 (javascript) (0) | 2024.01.03 |
[백준] 전화 요금 (javascript) (0) | 2023.10.19 |