https://www.acmicpc.net/problem/1699
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
|
import java.util.Scanner;
public class Main {
public static int n;
public static int[] arr;
public static int[] dp;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
dp = new int[n + 2];
dp[1] = 1;
for (int i = 2; i <= n; i++) {
dp[i] = i;
for (int j = 1; j * j <= i; j++) {
dp[i] = Math.min(dp[i], dp[i - j * j] + 1);
}
}
System.out.println(dp[n]);
}
}
|
cs |
18번째 줄 처럼 dp[i]=i로 초기화시켜준다. <--정말 중요
dp[2]=Math.min(dp[2],dp[2-1]+1) 즉 min(2,2)이므로 2
dp[3]=Math.min(dp[3],dp[3-1]+1) 즉 min(3,3)이므로 3
dp[4]는 i가 1일 때
Math.min(dp[4],dp[4-1]+1) => min(4,4) 이므로dp[4]=4
i가 2일때
Math.min(dp[4],dp[4-4]+1) =>min(4,1) 이므로 dp[4]=1이다.
dp[4]는 2의 제곱 한개만으로 만들 수 있기 때문에
for (int j = 1; j * j <= i; j++) {
dp[i] = Math.min(dp[i], dp[i - j * j] + 1);
}
위의 코드를 통해 제곱수 판별이 된 것을 알 수 있다.
문제를 풀면서 틀린부분
dp[i]=Math.min(dp[i],dp[i-j]+1)의 점화식을 생각해봤지만, 제곱수를 어떻게 다뤄야할지 도저히 감이 안왔다. 그래서 아래 링크에 있는 글을 봤는데,
https://www.acmicpc.net/board/view/13407
답글을 보면 동전교환 알고리즘을 이용해서 풀어보라고 해서 동전교환 알고리즘을 찾아보았다.
https://withhamit.tistory.com/333
--> 위 블로그 글이 설명을 잘 해주셨다.
d[i][j] = d[i-1][j] (0 <= j < cost[i])
= d[i][j-cost[i]] + d[i-1][j]
이 글도 보면서 참고해봤다!
'알고리즘 > DP' 카테고리의 다른 글
[java 백준] 실버 3/9461번 파도반 수열 (0) | 2021.08.10 |
---|---|
[java 백준] 실버 1/ 11052번 카드 구매하기 (0) | 2021.08.10 |
[DP기초] 필요한 동전의 최소개수 구하기 (0) | 2021.08.06 |
[DP기초] 계단오르기 (0) | 2021.08.06 |
[java 백준] 실버 2/ 11055번 가장 큰 증가 부분 수열 (0) | 2021.08.05 |
댓글