d[n]을 n번 눌러서 출력할 수 있는 A의 최대 개수라고 하자.
마지막 입력 그러니까 n-1에서 n으로 넘어가는 입력에 따라 경우를 나누어보자.
1. 마지막에 1를 눌렀을 경우
d[n-1]에서 A가 하나 추가되니 d[n]은 d[n-1]+1이다.
2. 마지막에 2를 눌렀을 경우
마지막에 2를 누르는 경우는 최대값이 될 수가 없음으로 무시
3. 마지막에 3을 눌렀을 경우
마지막에 3을 누르는 경우 또한 최대값이 절대 될 수가 없음으로 무시
4. 마지막에 4를 눌렀을 경우
n이 7이상인 모든 경우엔 마지막에 4를 누르고 끝나야 최대값이다.
4를 눌렀다는 것은 2와 3을 이전에 수행했다는 뜻.
고로 n-3때 2를 누르고 n-2때 3, n-1에 4를 누르는 경우이다.
그러므로 d[n] = 2*d[n-3]
그러나 4를 연속해서 누르는 경우도 있을 것이다.
n-4때의 상황을 복사해서 n-2때 4, n-1때도 4를 누른다면
d[n] = 3*d[n-4]
이것을 점화식으로 표현한다면
d[n] = (j+1) * d[n-(j+2)]
고로 7부터 입력된 수까지 최대값을 구하면 된다. 왜 7부터냐면 , d[1] ~ d[6]은 1~6이 최대이기 때문이다. (1만 누름)
코드
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 29 | #include<stdio.h> #include<iostream> #include<algorithm> using namespace std; int n; long long d[101]; int main() { cin >> n; d[1] = 1; d[2] = 2; d[3] = 3; d[4] = 4; d[5] = 5; d[6] = 6; for (int i = 7; i <= 100; i++) { for (int j = 1; j <= i-3; j++) { d[i] = max(max(d[i - 1] + 1, (d[i - (j+2)] * (j + 1))), d[i]); } } cout << d[n]; } | cs |
P.S
다이나믹 프로그래밍 문제는 진짜 넘 어렵당..
문제를 읽자마자 생각난 로직으로 프로그래밍을 시작하는 것보다
문제를 차근차근 곱씹어보고 경우도 나누어보고 규칙도 찾아본다음 코드를 짜는게 효율적일 것 같다.
그러므로 DP는 단순히 코딩을 잘한다고 해서 해결할 수 있는 문제가 아니라
문제를 읽어내는 눈이 필요시되는 것 같다.
한마디로 졸라 어렵다는 뜻이다.
'BOJ' 카테고리의 다른 글
백준 12865 / 평범한 배낭 (0) | 2019.02.13 |
---|---|
백준 11066 / 파일 합치기 (0) | 2019.02.13 |
백준 2293 / 동전 1 (0) | 2019.02.10 |
백준 15989 / 1,2,3 더하기 4 (0) | 2019.02.10 |
백준 10942 / 팰린드롬? (0) | 2019.02.09 |