-
13398번 연속합 2 / BOJ백준 2020. 3. 23. 13:42728x90
13398번 연속합 2 / BOJ
문제링크 : https://www.acmicpc.net/problem/13398
제출링크 : https://www.acmicpc.net/source/18618083
자바소스 : https://github.com/skysign/WSAPT/blob/master/BOJ/13398%EB%B2%88%20%EC%97%B0%EC%86%8D%ED%95%A9%202/src/Main.java이 문제를 풀기 전에, 1912번 연속합 / BOJ 문제를 꼭 풀어보시고,
여기 참고하세요 → https://skysign.tistory.com/193Dynamic Programming과 Prefix Sum을 사용해서 푸는 문제입니다.
이 문제에 대한 설명은 여기 참고하세요 → https://cooling.tistory.com/3자세한 설명은 추후에 시간이 나면 추가하겠습니다. ^^a
import java.io.BufferedWriter; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.DataInputStream; import java.io.FileInputStream; import java.util.ArrayList; import java.util.Arrays; /** * 13398번 연속합 2 / BOJ * 문제링크 : https://www.acmicpc.net/problem/13398 * 제출링크 : https://www.acmicpc.net/source/18618083 * 문제해설 : https://skysign.tistory.com/194 */ /** * 테스트 케이스 * 1 * -1 * 답 -1 * 여기서 답으로 0이 나오면 틀린 값입니다. * 한개를 삭제한다는 조건 보다, 한개이상 선택해야 한다는 조건이 우선입니다. * * 10 * 1 -1 1 -1 1 -1 1 -1 1 -1 * 답 2 * * 3 * -1 -1 -1 * 답 -1 * * 2 * 1 -3 * 답 1 * * 2 * -3 1 * 답 1 * * 3 * -1 1 0 * 답 1 * * 3 * -1 0 1 * 답 1 * * 3 * 0 1 -1 * 답 1 * * 3 * 1 0 -1 * 답 1 * * 3 * 1 -1 1 * 답 2 * * 3 * -1 1 1 * 답 2 * * 3 * 1 1 -1 * 답 2 * * 3 * -1 -1 1 * 답 1 * * 3 * 1 -1 -1 * 답 1 * * 3 * -1 1 -1 * 답 1 */ public class Main { int N; static int MY_MIN_VALUE = -100000; public void solve() throws IOException { N = sc.nextInt(); int[] dt = new int[N]; for (int i = 0; i < N; ++i) { dt[i] = sc.nextInt(); } int[] dpL2R = new int[dt.length +1]; long r = getSequenceNumberMax(dt, dpL2R); dpL2R[0] = Integer.MIN_VALUE; if(N>1) { int[] dpR2L = new int[dt.length +1]; for(int i=N-1; i>=0; --i) { dpR2L[i] = Math.max(dt[i], dt[i] + dpR2L[i+1]); } dpR2L[N] = Integer.MIN_VALUE; // 하나 제거하는 수의 인덱스가 i 라고 할 때, for(int i=0; i<N; ++i) { // 0 부터 시작해서 i-1까지, 연속된 수의 최대 값 // (연속된 수에 i-1은 포함되어있음) // dpL2R[i]; r = Math.max(r, (long)dpL2R[i]); // i+1 부터 시작해서 N-1까지, 연속된 수의 최대 값 // (연속된 수에 i+1은 포함되어있음) // dpR2L[i+1]; r = Math.max(r, (long)dpR2L[i+1]); // 왼쪽 0~i-1 과 오른쪽 i+1 ~ N-1, 양쪽의 합 r = Math.max(r, (long)dpL2R[i] + (long)dpR2L[i+1]); } } println(r); } public int getSequenceNumberMax(int[] dt, int[] dp) { int r = Integer.MIN_VALUE; for(int i=1; i<dt.length+1; ++i) { dp[i] = Math.max(dt[i-1], dt[i-1] + dp[i-1]); r = Math.max(r, dp[i]); } return r; } // * 아이디어 // 하나빼는 것을 실제로 빼지 말고, 0 으로 바꿔서 // 연속된 수의 최대값 구하기 // // 답은 나오지만, 여전히 시간 초과로 오답 처리됨 // O(N^2) 이고, N 의 범위가 1≤n≤100,000 // worst case 는 10,000,000,000 약 100억번 // 1억~5억 정도가 1초안에 실행될 것으로 예상하는대, // 100억번은 1초안에 실행되기에는 무리임 // // O(N)으로 문제를 해결해야 함 // // public void solve() throws IOException { // N = sc.nextInt(); // int[] dt = new int[N]; // // for(int i=0; i<N; ++i) { // dt[i] = sc.nextInt(); // } // // int r = getSequenceNumberMax(dt); // // for(int i=0; i<N; ++i) { // int tmp = dt[i]; // dt[i] = 0; // r = Math.max(r, getSequenceNumberMax(dt)); // dt[i] = tmp; // } // // println(r); // } // // // + O(N) N 개 입력 받기 // // + O(N) N 개에서 하나도 빼지 않고, 연속된 수의 최대값 // // O(N^2) N개 에서 하나씩 빼면서, 연속된 수의 최대값 구하기 // // public int getSequenceNumberMax(int[] dt) { // int dp[] = new int[dt.length +1]; // int r = Integer.MIN_VALUE; // // for(int i=1; i<dt.length+1; ++i) { // dp[i] = Math.max(dt[i-1], dt[i-1] + dp[i-1]); // r = Math.max(r, dp[i]); // } // // return r; // } // * 아이디어 // ArrayList를 사용해서, 한개를 제거한 배열을 만들고, 연속된 수의 최대갑 구하기 // // 답은 나오지만, 제출하면 시간 초과로 오답 처리 됨, 시간이 오래 걸린 것으로 예상되는 부분 // - ArrayList에서 하나 삭제하기 // - ArrayList에서 하나 삭제한 다음에, 배열로 만들기 // - ArrayList에서 하나 추가하기 // // public void solve() throws IOException { // N = sc.nextInt(); // al = new ArrayList<>(); // // for(int i=0; i<N; ++i) { // al.add(sc.nextInt()); // } // // int max = Integer.MIN_VALUE; // // for(int i=0; i<N; ++i) { // int tmpRemoved = al.get(i); // al.remove(i); // Integer[] dt = new Integer[al.size()]; // dt = al.toArray(dt); // int myMax = getSequenceNumberMax(dt); // max = Math.max(max, myMax); // al.add(i, tmpRemoved); // } // // println(max); // } // // public int getSequenceNumberMax(Integer[] dt) { // int dp[] = new int[dt.length +1]; // int r = Integer.MIN_VALUE; // // for(int i=1; i<dt.length+1; ++i) { // dp[i] = Math.max(dt[i-1], dt[i-1] + dp[i-1]); // r = Math.max(r, dp[i]); // } // // return r; // } public void _solve() throws IOException { solve(); bw.flush(); } public static void main(String[] args) throws IOException { Main main = new Main(); main._solve(); } public class MNode<TV> extends Node { ArrayList<MNode<TV>> mChidren ; MNode(TV v) { super(v); mChidren = new ArrayList<>(); } } public class BNode<TV> extends Node { BNode<TV> mL; BNode<TV> mR; BNode(TV v) { super(v); } } public class Node<TV> { public TV mV; Node(TV v) { set(v); } public void set(TV v) { mV = v; } } public int[][] pSum2D(int[][] dt) { int[][] pSum2D = new int[dt.length][dt[0].length]; return _prefixSum2D(dt, pSum2D, dt.length, dt[0].length); } public int[][] pSum2D(int[][] dt, int[][] pSum2D) { return _prefixSum2D(dt, pSum2D, dt.length, dt[0].length); } public int[][] _prefixSum2D(int[][] dt, int[][] pSum2D, int I, int J) { pSum2D[0][0] = dt[0][0]; for(int j=1; j<J; ++j) { pSum2D[0][j] = dt[0][j] + pSum2D[0][j-1]; } for(int i=1; i<I; ++i) { pSum2D[i][0] = dt[i][0] + pSum2D[i-1][0]; } for(int i=1; i<I; ++i) { for(int j=1; j<J; ++j) { pSum2D[i][j] = dt[i][j] + pSum2D[i-1][j] + pSum2D[i][j-1] - pSum2D[i-1][j-1]; } } return pSum2D; } public int area2DbyCnt(int[][] pSum2D, int i1, int j1, int i2, int j2) { return area2DbyIdx(pSum2D, i1-1, j1-1, i2-1, j2-1); } public int area2DbyIdx(int[][] pSum2D, int i1, int j1, int i2, int j2) { int r = pSum2D[i2][j2]; if(i1>0) r -= pSum2D[i1-1][j2]; if(j1>0) r -= pSum2D[i2][j1-1]; if((i1>0) && (j1>0)) r += pSum2D[i1-1][j1-1]; return r; } public int[][] rotate90(int[][] a, int N) { int[][] tp = new int[N][N]; for(int i=0; i<N; ++i) { for(int j=0; j<N; ++j) { tp[i][j] = a[N-1-j][i]; } } return tp; } public int[][] rotate180(int[][] a, int N) { int[][] tp = new int[N][N]; for(int i=0; i<N; ++i) { for(int j=0; j<N; ++j) { tp[N-i-1][N-j-1] = a[i][j]; } } return tp; } public int[][] rotate270(int[][] a, int N) { int[][] tp = new int[N][N]; for(int i=0; i<N; ++i) { for(int j=0; j<N; ++j) { tp[N-1-j][i] = a[i][j]; } } return tp; } public void flip_h(int[][] a, int N) { for(int i=0; i<N; ++i) { for(int j=0; j<N/2; ++j) { int tp = a[i][N-j-1]; a[i][N-j-1] = a[i][j]; a[i][j] = tp; } } } public void flip_v(int[][] a, int N) { for(int i=0; i<N/2; ++i) { for(int j=0; j<N; ++j) { int tp = a[N-i-1][j]; a[N-i-1][j] = a[i][j]; a[i][j] = tp; } } } public int[][] clone2D(int[][] src) { int N = src.length; int[][] dst = new int[N][N]; for (int i=0; i<N; i++) { System.arraycopy(src[i],0, dst[i],0, N); } return dst; } public class Pair<K, V> extends _Pair implements Comparable { public Pair(K key, V value) { super(key, value); } @Override public int compareTo(Object o) { Pair other = (Pair)o; int k1 = Integer.parseInt(this.getKey().toString()); int k2 = Integer.parseInt(other.getKey().toString()); if((k1 - k2) == 0) { int v1 = Integer.parseInt(this.getValue().toString()); int v2 = Integer.parseInt(other.getValue().toString()); return v1 - v2; } return k1 - k2; } } // http://cr.openjdk.java.net/~vadim/8140503/webrev.01/modules/base/src/main/java/javafx/util/Pair.java.html public class _Pair<K,V> { private K key; public K getKey() { return key; } private V value; public V getValue() { return value; } public _Pair(K key, V value) { this.key = key; this.value = value; } public boolean equals(Object o) { if (this == o) return true; if (o instanceof _Pair) { _Pair pair = (_Pair) o; if (key != null ? !key.equals(pair.key) : pair.key != null) return false; if (value != null ? !value.equals(pair.value) : pair.value != null) return false; return true; } return false; } } // Normally used MIN/MAX number public final int _1087654321 = 1087654321; public final int __1087654321 = -1087654321; public final int _987654321 = 987654321; public final int __987654321 = -987654321; // Commonly used numbers as a divider of mod operation to prevent overflow public final int _10_007 = 10007; public final int _1_000_000_007 = 1000000007; final int MOD = _1_000_000_007; public void print(int v) throws IOException { print(v+""); } public void print(String s) throws IOException { bw.write(s); } public void println() throws IOException { print("\n"); } public void println(int a) throws IOException { print(a+"\n"); } public void println(long a) throws IOException { print(a+"\n"); } public void println(double a) throws IOException { print(a+"\n"); } public void println(String s) throws IOException { bw.write(s+"\n"); } // -1 public final int MINUS_1 = -1; // 4 ways public int[] d4i = new int[]{-1, 1, 0, 0}; public int[] d4j = new int[]{0, 0, -1, 1}; // 8 ways public int[] d8i = new int[]{-1, 1, 0, 0, -1, -1, 1, 1}; public int[] d8j = new int[]{0, 0, -1, 1, -1, 1, 1, -1}; // Initialize 2D arrays with value v public void fill2D(int[][] _2D, int v) { for(int[] _1D: _2D) { Arrays.fill(_1D, v); } } public void fill2D(long[][] _2D, long v) { for(long[] _1D: _2D) { Arrays.fill(_1D, v); } } public void fill2D(double[][] _2D, double v) { for(double[] _1D: _2D) { Arrays.fill(_1D, v); } } public void print2D(int[][] dp) throws IOException { print(" "); for(int j=0; j<dp[0].length; ++j){ print(SS(j)+j + " "); } println(); for(int i=0; i<dp.length; ++i){ print(SS(i)+i+"|"); for(int j=0; j<dp[0].length; ++j){ print(SS(dp[i][j])+dp[i][j] + " "); } println(); } } public void print2D(long[][] dp) throws IOException { print(" "); for(int j=0; j<dp[0].length; ++j){ print(SS(j)+j + " "); } println(); for(int i=0; i<dp.length; ++i){ print(SS(i)+i+"|"); for(int j=0; j<dp[0].length; ++j){ print(SS(dp[i][j])+dp[i][j] + " "); } println(); } } public final int LENGHT_OF_NUMBER = 3; /** * Generate space string for alignment when we print 2D arrays. * its length is LENGHT_OF_NUMBER - the length of number * Basically, we assume that number a is less than 1000. * So, LENGHT_OF_NUMBER is 3 by default. * @param a * @return */ public String SS(int a) { String s = a+""; int l = LENGHT_OF_NUMBER - s.length(); StringBuilder sb = new StringBuilder(); for(int i=0; i<l; ++i) { sb.append(" "); } return sb.toString(); } public String SS(long a) { String s = a+""; int l = LENGHT_OF_NUMBER - s.length(); StringBuilder sb = new StringBuilder(); for(int i=0; i<l; ++i) { sb.append(" "); } return sb.toString(); } // Initialize 3D arrays with value v public void fill3D(int[][][] _3D, int v) { for(int[][] _2D: _3D) { for(int[] _1D: _2D) { Arrays.fill(_1D, v); } } } // GCD int GCD(int a, int b) { if(0 == b) { return a; } return GCD(b, a%b); } long GCD(long a, long b) { if(0 == b) { return a; } return GCD(b, a%b); } boolean IsEven(int a) { return (a>>1) == ((a>>1)<<1); } boolean IsOdd(int a) { return (a>>1) != ((a>>1)<<1); } boolean IsEven(long a) { return (a>>1) == ((a>>1)<<1); } boolean IsOdd(long a) { return (a>>1) != ((a>>1)<<1); } public Reader sc = new Reader(); // Sometimes, Reader class cause unknown problem, when I submit my java code to judge server. // For more detail, please see https://algospot.com/forum/read/4731/ // public Scanner sc = new Scanner(System.in); public BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out)); // https://www.geeksforgeeks.org/fast-io-in-java-in-competitive-programming/ public class Reader { final private int BUFFER_SIZE = 1 << 16; private DataInputStream din; private byte[] buffer; private int bufferPointer, bytesRead; public Reader() { din = new DataInputStream(System.in); buffer = new byte[BUFFER_SIZE]; bufferPointer = bytesRead = 0; } public Reader(String file_name) throws IOException { din = new DataInputStream(new FileInputStream(file_name)); buffer = new byte[BUFFER_SIZE]; bufferPointer = bytesRead = 0; } public String nextLine() throws IOException { byte[] buf = new byte[64]; // line length int cnt = 0, c; while ((c = read()) != -1) { if (c == '\n') break; buf[cnt++] = (byte) c; } return new String(buf, 0, cnt); } public int nextInt() throws IOException { int ret = 0; byte c = read(); while (c <= ' ') c = read(); boolean neg = (c == '-'); if (neg) c = read(); do { ret = ret * 10 + c - '0'; } while ((c = read()) >= '0' && c <= '9'); if (neg) return -ret; return ret; } public long nextLong() throws IOException { long ret = 0; byte c = read(); while (c <= ' ') c = read(); boolean neg = (c == '-'); if (neg) c = read(); do { ret = ret * 10 + c - '0'; } while ((c = read()) >= '0' && c <= '9'); if (neg) return -ret; return ret; } public double nextDouble() throws IOException { double ret = 0, div = 1; byte c = read(); while (c <= ' ') c = read(); boolean neg = (c == '-'); if (neg) c = read(); do { ret = ret * 10 + c - '0'; } while ((c = read()) >= '0' && c <= '9'); if (c == '.') { while ((c = read()) >= '0' && c <= '9') { ret += (c - '0') / (div *= 10); } } if (neg) return -ret; return ret; } private void fillBuffer() throws IOException { bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE); if (bytesRead == -1) buffer[0] = -1; } private byte read() throws IOException { if (bufferPointer == bytesRead) fillBuffer(); return buffer[bufferPointer++]; } public void close() throws IOException { if (din == null) return; din.close(); } } // public void test_matrix_methods() throws IOException { // // Test Case 1 // int m1[][] = { {1, 2, 3, 4}, // {5, 6, 7, 8}, // {9, 10, 11, 12}, // {13, 14, 15, 16} }; // // // Tese Case 2 // int m2[][] = { {1, 2, 3}, // {4, 5, 6}, // {7, 8, 9} }; // // println("Matrix Original"); // print2D(m1); // // println("Matrix Rotate 90"); // print2D(rotate90(m1, m1.length)); // // println("Matrix Rotate 180"); // print2D(rotate180(m1, m1.length)); // // println("Matrix Rotate 270"); // print2D(rotate270(m1, m1.length)); // // println("Matrix Flip Horizontal"); // int[][] m1h = clone2D(m1); // flip_h(m1h, m1h.length); // print2D(m1h); // // println("Matrix Flip Vertical"); // int[][] m1v = clone2D(m1); // flip_v(m1v, m1v.length); // print2D(m1v); // // println(); // // println("Matrix Original"); // print2D(m2); // // println("Matrix Rotate 90"); // print2D(rotate90(m2, m2.length)); // // println("Matrix Rotate 180"); // print2D(rotate180(m2, m2.length)); // // println("Matrix Rotate 270"); // print2D(rotate270(m2, m2.length)); // // println("Matrix Flip Horizontal"); // int[][] m2h = clone2D(m2); // flip_h(m2h, m2h.length); // print2D(m2h); // // println("Matrix Flip Vertical"); // int[][] m2v = clone2D(m2); // flip_v(m2v, m2v.length); // print2D(m2v); // } // // public void test_pSum2D_methods() throws IOException { // // Test Case 1 // int m1[][] = { {1, 1, 1, 1}, // {1, 1, 1, 1}, // {1, 1, 1, 1}, // {1, 1, 1, 1} }; // // println("Matrix Original"); // print2D(m1); // // int[][] m1pSum2D = new int[m1.length][m1[0].length]; // println("pSum2D"); // pSum2D(m1, m1pSum2D); // print2D(m1pSum2D); // // println(area2DbyIdx(m1pSum2D, 1, 1, 3, 3)); // println(area2DbyIdx(m1pSum2D, 0, 0, 3, 3)); // println(area2DbyIdx(m1pSum2D, 0, 1, 3, 3)); // println(area2DbyIdx(m1pSum2D, 1, 0, 3, 3)); // } }
728x90'백준' 카테고리의 다른 글
BOJ 4991번 로봇 청소기 (0) 2020.04.30 1976번 여행 가자 / BOJ (0) 2020.04.06 1912번 연속합 / BOJ (0) 2020.03.22 BOJ 11726번 2×n 타일링 (0) 2020.01.27 9095번 1, 2, 3 더하기 / BOJ / acmicpc.net (0) 2020.01.27