본문 바로가기
알고리즘/DP

[java 백준] 실버 2/ 11055번 가장 큰 증가 부분 수열

by Meaning_ 2021. 8. 5.
728x90
반응형

https://www.acmicpc.net/problem/11055

 

11055번: 가장 큰 증가 부분 수열

수열 A가 주어졌을 때, 그 수열의 증가 부분 수열 중에서 합이 가장 큰 것을 구하는 프로그램을 작성하시오. 예를 들어, 수열 A = {1, 100, 2, 50, 60, 3, 5, 6, 7, 8} 인 경우에 합이 가장 큰 증가 부분 수

www.acmicpc.net

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
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();
        arr = new int[n + 2];
        dp = new int[n + 2];
 
        for (int i = 1; i <= n; i++) {
 
            arr[i] = sc.nextInt();
 
        }
        dp[1= arr[1];
 
        for (int i = 2; i <= n; i++) {
            dp[i] = arr[i];
            int maxDp = 0;
            for (int j = 1; j < i; j++) {
 
                if (arr[i] > arr[j]) {
                    maxDp = Math.max(maxDp, dp[j]);
                    
                    dp[i] = maxDp + arr[i];
 
                }
            }
        }
 
        int max = dp[1];
        for (int i = 1; i <= n; i++) {
            if (dp[i] > max) {
                max = dp[i];
            }
 
        }
 
        System.out.println(max);
 
    }
 
}
cs

 

 

 

11053번 문제와 매우 유사한 문제이다

https://we1cometomeanings.tistory.com/86

 

[java 백준] 실버 2/11053번 가장 긴 증가하는 부분 수열

https://www.acmicpc.net/problem/11053 11053번: 가장 긴 증가하는 부분 수열 수열 A가 주어졌을 때, 가장 긴 증가하는 부분 수열을 구하는 프로그램을 작성하시오. 예를 들어, 수열 A = {10, 20, 10, 30, 20,..

we1cometomeanings.tistory.com

 

문제를 풀면서 놓친 부분


1. dp[i]=dp[j]+arr[i]

1
2
3
4
5
6
7
8
9
10
11
dp[1] = arr[1];
 
        for (int i = 2; i <= n; i++) {
            dp[i] = arr[i];
            for (int j = 1; j < i; j++) {
                if (arr[i] > arr[j]) {
                    dp[i] += arr[j];
                    
                }
            }
        }
cs

 

7번째 줄 처럼 dp[i]+=arr[j]라고 점화식을 짜버리면 

100 110 90 80 70 80 90 1 2 3 일때, 

 

dp[7]=70+80+90=240 이여야 하는데, arr[4]인 80도 arr[7]인 90보다 작기 때문에 80+70+80+90=320이 되버린다. 그렇기 때문에 240이 나오기 위해서는 

if(arr[i]>arr[j]){

 dp[i]=dp[j]+arr[i]

}

   

2. 최대값 

 

하지만

dp[i]=dp[j]+arr[i] 이렇게만 써버리면  2,1,5,6,7일때, 예외가 발생한다.

 

예를 들어 dp[3]을 구한다고 해보자. 그러면 i는 3일 것이고 j를 1부터 2까지 돌려보겠다.

 

i=3이고, j는 1일 때 --> 2<5 이므로 if 조건을 만족시킨다. dp[3]=dp[1]+arr[3]을 하면 dp[3]=7이다.

i=3이고 j=2일때 1<5이므로 if 안에 조건을 만족시킨다. dp[3]=dp[2]+arr[3] 을 하면 dp[2]=1 (arr[2]가 arr[1]보다 작으므로 dp[2]=arr[2]가 된다) 에 5를 더하면 6이 된다.

 

이렇게 되면 j가 1일때 (7)가 j가 2일 때(6) 보다 크지만 j가 2일때가 1보다 늦게 나오기 때문에 dp[3] 값을 덮어쓰므로 결론적으로 dp[3]=6이된다. 

 

그래서 2,1,5,6,7 일 때 답은 20이여야하지만 dp[i]=dp[j]+arr[i] --> 얘를 써버리면 답은 19가 된다.

 

그러면 감이 올거다 바로 max를 쓰면된다 j가 1일때랑 j가 2일 때 중 더 큰 값을 골라서 걔를 dp[i]에 더해주면 된다. 

 

for (int i = 2; i <= n; i++) {

            dp[i] = arr[i];

            int maxDp = 0;

            for (int j = 1; j < i; j++) {

 

                if (arr[i] > arr[j]) {

                    maxDp = Math.max(maxDp, dp[j]);

                    

                    dp[i] = maxDp + arr[i];

 

                }

            }

        }

 

 

 

 

 

 

반레를 알아보고 싶을 때


 

https://squareyun.tistory.com/18

 

[Java] 백준 11055 : 가장 큰 증가 부분 수열

문제 링크 1. 1시간 소요. 점화식 세우는 아이디어는 금방 떠올라서 코드를 쭉쭉 써내려 갔다. 그러나 오답처리가 되어 질문 검색을 통해 반례를 찾아서 수정하는 데에 오랜 시간이 걸렸다. 점화

squareyun.tistory.com

https://geehye.github.io/baekjoon-11055/#

 

DynamicProgramming 백준 알고리즘 자바 11055 ‘가장 큰 증가 부분 수열’ 문제풀이

Problem수열 A가 주어졌을 때, 그 수열의 증가 부분 수열 중에서 합이 가장 큰 것을 구하는 프로그램을 작성하시오.예를 들어, 수열 A = {1, 100, 2, 50, 60, 3, 5, 6, 7, 8} 인 경우에 합이 가장 큰 증가 부분

geehye.github.io

 

728x90
반응형

댓글