Search Results for '2008/01'

17 POSTS

  1. 2008/01/28 [UVA] 103 Stacking Boxes

[UVA] 103 Stacking Boxes

Posted 2008/01/28 17:49
- 문제 다운받기

이번 문제는 문제를 이해하는데 좀 오래걸렸다. 문제가 길고 Input이 정형화되어 있지만 얼핏 보기에는 정형화되어 있는 것 같지 않아서 해석하는데 힘들었다. 해석이 끝난 후 바로 동적계획법 문제임을 알아차렸고 기분좋게 한번에 Accept를 받았다.


점화식은 다음과 같다.

(i,j)의 2차원 배열에서 k개의 box거 있을경우
sigma i=1 to k
  - if  i = j   then result(i,j) = maxValue(column i) -> i번째 column중 최대값
  - if box(i) < box(j) then = result(i,i) + 1 -> i,i에서의 결과 + 1
  - 결과의 출력은 length가 가장 긴 maxLength부터 뒤로 따라간 후 재귀로 출력한다.


6200930 Stacking Boxes Accepted JAVA 0.160 2008-01-28 06:43:09


import
 java.io.IOException;
import java.util.Arrays;
import java.util.Comparator;
import java.util.StringTokenizer;

public class Main {
        public static String readLn (int maxLg) {
                byte lin[] = new byte [maxLg];
                int lg = 0, car = -1;

                try {
                        while (lg < maxLg) {
                                car = System.in.read();
                                if ((car < 0) || (car == '\n')) break;
                                lin [lg++] += car;
                        }
                }
                catch (IOException e) {
                        return (null);
                }

                if ((car < 0) && (lg == 0)) return (null);
                return (new String (lin, 0, lg));
        }
       
        int boxCount;          // box의 개수 (Line수)
        int boxLength;         // 측정된 box의 길이 (한 Line당 숫자 개수)
        int maxLength;         // Property를 만족하는 최대 box의 개수
        int[][] boxMap;                // 입력된 Box의 정보를 저장
        int[][] resultMap;     // 동적계획법으로 문제를 해결하는데 사용
       
        public Main() {
                String line;
       
                // 입력을 받는다.
                while((line = readLn(255)) != null) {
                        StringTokenizer in = new StringTokenizer(line);
                        boxCount = Integer.parseInt(in.nextToken());
                        boxLength = Integer.parseInt(in.nextToken());
                       
                        init();
                        start();
                        print();
                }
        }
       
        /**
         * 변수를 초기화한다.
         */
        public void init() {
                boxMap = new int[boxCount+1][];
                boxMap[0] = new int[boxLength+1];
                resultMap = new int[boxCount+1][boxCount+1];
                resultMap[1][1] = 1;
                maxLength = 0;
               
                int[] boxArray;
               
                int i, j;
                for(i=0 ; i<boxCount ; i++) {
                        boxArray = new int[boxLength+1];
                        boxArray[0] = i+1;
                       
                        StringTokenizer in = new StringTokenizer(readLn(255));
                       
                        for(j=0 ; j<boxLength ; j++)
                                boxArray[j+1] = Integer.parseInt(in.nextToken());
                       
                        // 입력받은 한 Line(Box)의 정보를 정렬한다. (0번째는 순차적으로 번호를 부여한다.)
                        Arrays.sort(boxArray, 1, boxLength+1);
                        boxMap[i+1] = boxArray;
                }
               
                // 2차원 배열을 정렬한다.
                Arrays.sort(boxMap, new Comparator<int[]>() {
                        public int compare(int[] arr1, int[] arr2) {
                                int i;
                                for(i=1 ; i<=boxLength ; i++)
                                        if(arr1[i] < arr2[i])
                                                return -1;
                                return 1;
                        }
                });
        }
       
        /**
         * 동적계획법으로 문제의 Longest String을 구한다.
         */
        public void start() {
                int i, j;
                for(i=1 ; i<=boxCount ; i++) {
                        for(j=i ; j<=boxCount ; j++) {
                                // i와 j가 같을 경우 (i,j)의 값은 현재 Column의 Max값이다.
                                if(i == j) {
                                        resultMap[i][j] = getMaxValue(i);
                                        maxLength = Math.max(resultMap[i][i], maxLength);
                                        continue;
                                }
                               
                                // boxMap[i]가 boxMap[j]보다 작을 경우
                                // resultMap[i][j]는 lengthArray[i](i번째 box의 최대 length) + 1이다.
                                if(compare(boxMap[i], boxMap[j]) < 0)
                                        resultMap[i][j] = resultMap[i][i] + 1;
                        }
                }
        }
       
        /**
         * 결과를 출력한다.
         */
        public void print() {
                // maxLength를 출력한다.
                System.out.println(maxLength);
               
                // path를 출력한다.
                int i;
                for(i=1 ; i<=boxCount ; i++) {
                        if(resultMap[i][i] == maxLength) {
                                printPath(i);
                                break;
                        }
                }
                System.out.println();
        }
       
        /**
         * index번째 박스의 앞의 박스들과 index번째 박스를 출력한다.
         * @param index
         */
        private void printPath(int index) {
                if(resultMap[index][index] == 1) {
                        System.out.print(boxMap[index][0]);
                        return;
                }
               
                int i;
                for(i=index-1 ; i>=1 ; i--) {
                        if(resultMap[index][index] == resultMap[i][index]) {
                                printPath(i);
                                System.out.print(" " + boxMap[index][0]);
                                break;
                        }
                }
        }
       
        /**
         * index번째 Column의 최대값을 얻어온다.
         * @param index 
         * @return
         */
        private int getMaxValue(int index) {
                int max = 0;
               
                int i;
                for(i=index ; i>=1 ; i--)
                        max = Math.max(resultMap[i][index], max);
                return max;
        }
       
        /**
         * arr1과 arr2를 비교한다. arr1의 모든 원소가 arr2의 모든 원소보다 작은지 여부를 검사한다.
         * @param arr1 박스1
         * @param arr2 박스2
         * @return arr1이 arr2보다 모두 작으면 -1, 아니면 1
         */
        private int compare(int[] arr1, int[] arr2) {
                int i;
                for(i=1 ; i<=boxLength ; i++)
                        if(arr1[i] >= arr2[i])
                                return 1;
                return -1;
        }
        
        public static void main(String[] args) {
                new Main();
        }
}

'C.S.E > Algorithm' 카테고리의 다른 글

[ACM-ICPC 2007] Problem D - Phone 해결2  (2) 2008/02/05
[ACM-ICPC 2007] Problem D - Phone  (0) 2008/02/05
[UVA] 103 Stacking Boxes  (0) 2008/01/28
[UVA] 102 Ecological Bin Packing  (0) 2008/01/26
[UVA] 101 The Blocks Problem  (0) 2008/01/26
[UVA] 100 The 3N + 1  (0) 2008/01/25
« PREV : 1 : 2 : 3 : 4 : 5 : ... 17 : NEXT »