BOJ#11058 크리보드
* 문제
* 풀이
- dp[i] : 버튼을 i번 눌렀을 때, 화면에 출력할 수 있는 A의 최대 개수
dp를 위와 같이 정의하고, 문제를 분석하면서 몇가지 성질을 찾아보았습니다.
0. i가 클수록 dp[i]가 무조건 크다.
1. i가 커질수록 인접한 dp값들의 차이가 커진다.
2. dp[i]의 값은 무조건 dp[i-3] * 2보다 무조건 크거나 같다. 또한 dp[i-3]의 값은 dp[i-6] * 2 보다 무조건 크거나 같다....
3. i가 일정 수준 이상이면(7이상), 이제는 A를 하나 추가하는 버튼은 필요가 없다. 복사-붙여넣기 동작만 하는 것이 A를 최대로 출력할 수 있다.
4. dp[i] 값은 i번째에 1) A를 하나 추가한 경우, 2) 버퍼에서 Ctrl + V한 경우 2가지로 나눌 수 있을 것이다.
4-1) i번째에 A를 하나 추가한 경우
dp[i] = N;
dp[i] = Max(dp[i], dp[i-1]+1)
4-2) i번째에 버퍼에서 Ctrl + V한 경우
dp[i] = Max(dp[i], dp[i-3] * 2)
dp[i] = Max(dp[i], dp[i-4] * 3)
dp[i] = Max(dp[i], dp[i-5] * 4)
dp[i] = Max(dp[i], dp[i-6] * 5)
........
이제 4-1)과 4-2)를 이용해서 구현하면 되는데
4-2)의 경우 어디까지 검사를 할 것인가..에 대해 고민을 해보면 되겠습니다.
끝까지(1까지) 검사를 할 수도 있겠지만,
대충 i-3에서 최소 i-5, 최대 10개까지만 검사를 하면 충분히 답을 얻을 수 있겠습니다.
* 나의 코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* BOJ#11058 크리보드
* https://www.acmicpc.net/problem/11058
*/
public class Main {
static long[] dp = new long[101]; // dp[i] : 버튼을 i번 눌러서 화면에 출력할 수 있는 A의 최대 개수
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
System.out.println(solve(N));
}
// return dp[N];
static long solve(int N) {
if (N <= 0) {
return 0;
}
if (N == 1) {
return dp[N] = 1;
}
if (dp[N] > 0) return dp[N];
dp[N] = N;
dp[N] = Math.max(dp[N], solve(N - 1) + 1);
int j = 2;
for (int i = N - 3; i > N - 6; i--) {
dp[N] = Math.max(dp[N], solve(i) * j);
j++;
}
return dp[N];
}
}
'Algorithm > DP' 카테고리의 다른 글
BOJ#12101 1, 2, 3 더하기 2 (0) | 2017.04.06 |
---|---|
BOJ#11048 이동하기 (0) | 2017.04.06 |
BOJ#12969 ABC (0) | 2017.04.05 |
BOJ#13398 연속합2 (1) | 2017.04.04 |
BOJ#1520 내리막 길 (0) | 2017.03.31 |