Dynamic Programming
알고리즘 수업 때 배웠는데.. 머리에 남는게 없다…
재귀(recursive)만 기억난다…
피보나치 수열을 풀 때 가장 기본적으로
if(n<=1){
return n;
}else{
return f(n-1) + f(n-1);
이렇게 하는데
DP를 통해 for문을 돌리면
f(0) = 0;
f(1) = 1;
for(int i=2; 2<n; i++){
f(i) = f(i-1) + f(i-2);
}
return f(n);
피보나치 수열을 풀 때 f(2) = f(1) + f(0)을 계속 반복하면
f(3)을 구할 때 이미 구한 f(2)를 그대로 쓰면 되니까 더 효율적이다.
이게 DP의 핵심!!
재귀함수라도 이미 계산한건 또하지 말자는 것이다.
1) 먼저 scanner로 n, A를 받는다
2) A[0], A[1] 비교해 더 큰 값을 k에 저장
3) for(i=2; i<n; i++)에서 k보다 A[i]가 더 크면 값을 k에 저장, j++
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
int A[] = new int[N];
int i,k,j;
for(i = 0; i < N; i++) {
A[i] = sc.nextInt();
}
if(A[0] < A[1]) {
j = 1;
k = A[1];
}else {
j = 0;
k = A[0];
}
for(i = 2; i < N; i++) {
if(k < A[i]) {
k = A[i];
j++;
}
}
System.out.println(j);
}
}
❌ 오답
f(1) = a
f(2) = b
f(3) = a + b
f(4) = a + 2b
f(5) = 2a + 3b
f(6) = 3a + 5b
……
f(N)일 경우는 F를 피보나치 값이라 할 때
f(N) = F(N-2) * a + F(N-1) * b
피보나치 수열의 값들을 길이가 D인 배열에 저장
K = F(D-2) * a + F(D-1) * b
맞는 값이 나올 때까지 for 루프 돌리기
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int D = sc.nextInt();
int K = sc.nextInt();
int a, b, i;
int[] F = new int[D];
F[1] = 1;
F[2] = 1;
for(i = 3; i < D; i++) {
F[i] = F[i-2] + F[i-1];
}
for(a = 1; a < K; a++) {
if((K - F[D-2] * a) % F[D-1] == 0) {
b = (K - F[D-2] * a) / F[D-1];
System.out.println(a);
System.out.println(b);
}
}
}
}
처음에 제출할 때 K를 넣어야하는데 if와 for문 안에 D를 넣어놓고 답이 안나와서 멘붕이었다…ㅎ