1
+ import java .io .*;
2
+ import java .util .*;
3
+
4
+ //투포인터+dp : 1<=N<=100,000 > O(N)
5
+ public class YJ_20181 {
6
+ public static void main (String [] args ) throws IOException {
7
+ BufferedReader br = new BufferedReader (new InputStreamReader (System .in ));
8
+ String [] data = br .readLine ().split ("\\ s" );
9
+ int n = Integer .parseInt (data [0 ]);
10
+ int k = Integer .parseInt (data [1 ]);
11
+ StringTokenizer st = new StringTokenizer (br .readLine ());
12
+ int [] branch = new int [n +1 ];
13
+ for (int i =0 ; i <n ; i ++){
14
+ branch [i ] = Integer .parseInt (st .nextToken ());
15
+ }
16
+
17
+ int start = 1 ;
18
+ int end = 0 ;
19
+ int satisfaction =branch [0 ];
20
+ long [] dp = new long [n +1 ]; // dp[현재지점] = 최대 누적 탈피 에너지
21
+
22
+ //k 보다 작으면 start를 움직이고, k 를 넘으면 end 를 움직이기 때문에 start 와 end 범위가 슬라이딩 윈도우 형태로 이동됨
23
+ while (start < n +1 ){
24
+ if (satisfaction < k ){
25
+ dp [start ] = Math .max (dp [start ],dp [start -1 ]); //현재까지의 최대 에너지 갱신
26
+ if (start < n +1 ){
27
+ satisfaction += branch [start ++]; //k 보다 작으면 start 오른쪽으로 이동
28
+ }
29
+ }else {
30
+ while (satisfaction >= k ){
31
+ //기존 누적 최대에너지 vs 이전 상태로 돌아가서 현재 구간에 대한 에너지
32
+ //start 가 1부터 시작했기 때문에 end 가 투포인터 범위에 포함되지 않는 이전 상태가 됨
33
+ dp [start ] = Math .max (dp [start ], dp [end ] + satisfaction - k );
34
+ satisfaction -= branch [end ++]; //end 오른쪽으로 이동 시켜서 범위 좁히기
35
+ }
36
+ }
37
+ }
38
+ System .out .println (dp [n ]);
39
+ }
40
+ }
0 commit comments