Created
September 20, 2016 13:45
-
-
Save developer-sdk/49220a68012b040af5694388a373728f to your computer and use it in GitHub Desktop.
정올, 1539, 다이나믹프로그래밍, 가장높은탑쌓기
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package sdk.algo.dynamic; | |
| import java.util.ArrayList; | |
| import java.util.Arrays; | |
| import java.util.Collections; | |
| import java.util.Comparator; | |
| import java.util.Scanner; | |
| /** | |
| * 정올, 다이나믹, 1539 가장높은 탑 쌓기 | |
| * | |
| * @author whitebeard | |
| * | |
| */ | |
| public class Problem1539 { | |
| public static void main(String[] args) { | |
| Scanner in = new Scanner(System.in); | |
| int N = in.nextInt(); | |
| int[][] bricks = new int[N][4]; | |
| for (int i = 0; i < N; i++) { | |
| bricks[i][0] = in.nextInt(); // 밑면의 넓이 | |
| bricks[i][1] = in.nextInt(); // 벽돌의 높이 | |
| bricks[i][2] = in.nextInt(); // 무게 | |
| bricks[i][3] = i + 1; // 원래 인덱스(최종 출력을 위해 +1 처리) | |
| } | |
| in.close(); | |
| // 테스트 데이터 #1 | |
| // int N = 5; | |
| // int[][] bricks = {{ 25, 3, 4, 1 }, | |
| // { 4, 4, 6 , 2}, | |
| // { 9, 2, 3 , 3}, | |
| // { 16, 2, 5 , 4}, | |
| // { 1, 5, 2 , 5}}; | |
| // 테스트 데이터 #2 | |
| // int N = 10; | |
| // int[][] bricks = { { 114, 96, 290, 1 }, | |
| // { 65, 74, 201, 2 }, | |
| // { 261, 19, 105, 3 }, | |
| // { 181, 60, 275, 4 }, | |
| // { 90, 145, 254, 5 }, | |
| // { 286, 118, 64, 6 }, | |
| // { 16, 24, 205, 7 }, | |
| // { 288, 128, 299, 8 }, | |
| // { 96, 36, 74, 9 }, | |
| // { 182, 5, 35, 10 }}; | |
| // 밑면의 넓이 기준 정렬 | |
| Arrays.sort(bricks, new Comparator<int[]>() { | |
| @Override | |
| public int compare(int[] a, int[] b) { | |
| return (a[0] <= b[0]) ? -1 : 1; | |
| } | |
| }); | |
| // 벽돌 정렬 결과 출력 | |
| // for(int[] brick : bricks) | |
| // System.out.printf("%2d\t%2d\t%2d\t%2d\n", brick[0], brick[1], | |
| // brick[2], brick[3]); | |
| // 넓이가 가장 작은 벽돌 위에는 아무것도 올라갈 수 없으므로 result의 첫번째에는 첫번째 벽돌을 입력 | |
| int[][] result = new int[N][3]; | |
| result[0][0] = 0; // 올라갈 인덱스 | |
| result[0][1] = bricks[0][3]; // 원인덱스 | |
| result[0][2] = bricks[0][1]; // 높이 | |
| // 두번째 넓이의 벽돌부터 | |
| for (int i = 1; i < bricks.length; i++) { | |
| // 자신보다 작은 넓이의 벽돌을 순회하면서 확인 | |
| for (int k = 0; k < i; k++) { | |
| if (bricks[i][2] > bricks[k][2]) { // 무게가 작아 올라갈 수 있다면 | |
| if (result[i][2] < bricks[i][1] + result[k][2]) { | |
| // 현재 벽돌과 올라간 벽돌의 높이의 합이 이전에 가장 높은 벽돌의 높이보다 크다면 | |
| result[i][0] = k; | |
| result[i][1] = bricks[k][3]; | |
| result[i][2] = bricks[i][1] + result[k][2]; | |
| } | |
| } | |
| } | |
| // 올라갈 수 있는 벽돌이 없으면 자신의 높이를 입력 | |
| if (result[i][2] == 0) { | |
| result[i][0] = i; | |
| result[i][1] = bricks[i][3]; | |
| result[i][2] = bricks[i][1]; | |
| } | |
| } | |
| // System.out.println("-------------------------"); | |
| // for(int[] brick : result) | |
| // System.out.printf("%2d\t%2d\t%2d\n", brick[0], brick[1], brick[2]); | |
| // 최고 높이의 인덱스 확인 | |
| int maxHeight = 0; | |
| int maxIndex = 0; | |
| for (int i = 0; i < result.length; i++) { | |
| if (result[i][2] > maxHeight) { | |
| maxHeight = result[i][2]; | |
| maxIndex = i; | |
| } | |
| } | |
| // 쌓여진 순서를 아래 벽돌부터 리스트에 입력 | |
| ArrayList<Integer> list = new ArrayList<>(); | |
| list.add(bricks[maxIndex][3]); | |
| while (true) { | |
| // 자신의 위에 아무것도 없으면 종료 | |
| if (result[maxIndex][0] == maxIndex) | |
| break; | |
| maxIndex = result[maxIndex][0]; | |
| list.add(bricks[maxIndex][3]); | |
| } | |
| // System.out.println("---------사이즈 출력-------------"); | |
| System.out.println(list.size()); | |
| // System.out.println("---------역순으로 위에서 부터 출력-------------"); | |
| Collections.reverse(list); | |
| for (int n : list) | |
| System.out.println(n); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment