규칙을 찾아 점화식을 만드는 문제.
한 번에 성공.
을 을 1로 만들기 위해 필요한 최소한의 연산 수라고 정의한다.
일때를 생각하자. 어떠한 연산도 하지 않는다. 따라서 이다.
일때를 생각하자.
2로 나누거나 1을 빼서 1을 만들 수 있다. 즉 이다.
일때를 생각하자.
1. 3으로 나누거나
2. 1을 뺀 후 2로 나누거나
3. 1을 뺀 후 다시 1을 빼거나
총 3가지 방법이 있다. 최솟값은 이다.
굵게 강조한 부분은 일때와 겹치는 부분이다. 그래프를 그려보면 그 관계를 단박에 확인할 수 있다.
일반화하면 다음과 같다.
이때, 1번과 2번 연산에 의해 다음과 같은 관계식이 주어진다.
이를 코드로 나타내면 다음과 같다.
#include <stdio.h>
#define MIN(x,y) x<y?x:y
int P[1000001];
int main()
{
int N,i;
scanf("%d",&N);
for(i=2;i<=N;i++) {
P[i]=P[i-1]+1;
if(i%2==0) P[i]=MIN(P[i], P[i/2]+1);
if(i%3==0) P[i]=MIN(P[i], P[i/3]+1);
}
printf("%d",P[N]);
}
이 문제는 재귀함수로도 풀 수 있다.
#include <stdio.h>
int N;
int c(int X){
int a,b;
if(X<2)return 0;
a=c(X/2)+X%2+1;
b=c(X/3)+X%3+1;
return a<b ? a : b;
}
int main(){
scanf("%d",&N);
printf("%d",c(N));
}
wh0tmdgus님 소스
-> https://www.acmicpc.net/source/5943375
관계를 찾아내니 쉬웠다.
그나저나 velog가 LaTeX의 그래프 기능을 제공하지 않아서 아쉽다. 그래프 그리는 걸 지원하면 괜찮았을텐데.