주제 링크 : https://codeforces.com/problemset/problem/1216/F
타이틀 효과 : 방 라우터 (방 번호 I에 대한 가격) 대신에 설치 될 수 n 개의 객실은 왼쪽과 라우터 범위 최대에있다 (1, I - K), n은 바로 최대 (에, 난 + K) 0 라우터), 방 대신에 설치 될 수없는 직접 방 번호 I 액세스 (가격 접속되는), 또는 네트워크 라우터 비용없이 방 설치 (문질러있다. Q.하자 N이 방은 모두 최소의 비용은 인터넷에 연결할 수 있습니다.
세그먼트 트리 유지 보수 DP로
i 번째의 위치 (0) / 방전 (1) 라우터, 소비 필요한 최소의 비용을 길게 1 커버 위치 완료된 - 제공자 DP는 [I]는 [0/1] 난 앞이다.
다음과 같은 상태 전환을 고려 :
내가 전에 가정 - 한 방에 모든 최소의 비용으로 인터넷에 연결할 수있다,
- 이 방 속성은 0 또는 1인지 여부이다 : DP [I] [0] = 분 {DP [전 - 1] [0] + 난 쿼리 (라우터 앞, 1, 1에 넣고, N, I - K , I - 1)};
이것은 즉, i 번째 방 홀드 라우터, 전 객실 전에 내가 이전에 연결된 모든 비용 인터넷 = 분 {- 1 개 침실 연결된 모든 최소의 비용으로 인터넷 + 비용에 직접 연결 전 객실 난 인터넷, 문지 앞 네트워크 라우터는 실내에 배치된다 (이 경우 대가 같은 공간 전송 비용이 앞에 넣어지게 라우터의 비용은이 시간을 소비하지 않고, i 번째 방)}
라우터 2. 상기 공간에 배치 될 수있다 : DP [I] [1] = 분 {쿼리 (라우터 앞 1,1- 듯 N I - K, I - 1), 조회 (전면 홀드 라우터 1 1, B, I - K - 1, I - 1)} + I;
이것은 I 룸 모두 최소의 비용으로 인터넷 필요 = 분 {[1 - K - - i가 1, I]를 접속하기 전에 제 i 객실 방전 라우터를 선택한다는 것을 의미 앞의 구간에서의 최소 사용 라우터 [ 전 - K, I - 1] 구간의 최소 라우터없이 방에 배치되어 선정 된 라우터} + I
1 #INCLUDE <iostream> 2 #INCLUDE <벡터> 3 #INCLUDE <지도> 4 #INCLUDE <알고리즘> 5 #INCLUDE <큐> 6 #INCLUDE <cstdio> 7 #INCLUDE <cmath> 8 #INCLUDE < 문자열 > 9 # 포함 < 설정 > 10 #INCLUDE <복합체> 11 #INCLUDE <cstdio> 12 #INCLUDE <CString을> 13 #INCLUDE <적층> 14 #INCLUDE <iomanip> 15 #INCLUDE <비트 세트> 16 #INCLUDE <소속 카테고리> 17 #INCLUDE <랜덤> 18#INCLUDE <unordered_map도> 19 #INCLUDE <unordered_set> 도 20은 사용 공간의 성병; 21 22 CONST의 INT maxn 2E5 + = 10 ; 23 CONST 긴 긴 INF = 0x3f3f3f3f3f3f3f3f ; 24 (25) INT의 N, K; 26 숯 STR [maxn]; 27 긴 긴 DP [maxn] [ 5 ]; 28 29 긴 긴 tree_no [maxn * 4 ]; 30 긴 긴 tree_yes [maxn * 4]; 31 32 공극 push_up ( 긴 길이 TMP [], INT의 RT) { 33 개 INT LS = RT * 2 , RS = RT의 * 2 + 1 ; 34 TMP [RT] = 분 (TMP [LS, TMP [RS]); 35 } 36 37 공극 빌드 ( 긴 길이 TMP [], INT의 RT, INT의 L, INT의 R) { 38 TMP [RT] = INF; 39 의 경우 (L == R) { 40 창 ; (41) } 42 INT 중간 = (L + R) / 2 ; 43 빌드 (TMP, 실온에서 * 2 , L, MID); 44 빌드 (TMP, 실온에서 * 2 + 1 , 중간 + 1 , R); 45 // push_up (TMP, RT); 46 } 47 48 긴 긴 질의 ( 긴 길이 TMP [], INT의 RT, INT의 L, INT R, INT QL, INT QR) { 49 의 경우 (QL <= 1 && R <= QR) 복귀 TMP [RT]; 50 INT 중간 = (L + R) / 2 ; 51 의 경우 (QR <= MID) 리턴 질의 (TMP, 실온에서 * 2 , L, 중간, QL, QR); (52) 그 밖의 경우 (QL> MID) 리턴 질의 (TMP, 실온에서 * 2 + 1 , 중간 + 1 , R, QL, QR); 53 다른 { 54 긴 긴 ans_ls = 쿼리 (TMP, 실온에서 * 2 , L, 중간, QL, QR); 55 긴 긴 ans_rs = 쿼리 (TMP, 실온에서 * 2 + 1 , 중간 + 1 , R, QL, QR); (56) 리턴 분 (ans_ls, ans_rs)를; 57 } 58 } 59 60 공극 업데이트 ( 긴 길이 TMP [], INT의 RT, INT의 L, INT의 R, INT의 P, 긴 길이 X) { 61 의 경우 (L == R) { 62 TMP [RT] =의 X; 63 창 ; 64 } 65 INT 중간 = (L + R) / 2 ; 66 의 경우 (p <= MID) 업데이트 (TMP, 실온에서 * 2 , L, 중, P, X); 67 다른 업데이트 (TMP, 실온에서 * 2 + 1 , 중간 + 1 , R, P, X); 68 push_up (TMP, RT); 69 } 70 71 INT 의 main () { 72 는 scanf ( " %의 D % d에 " , N, K); 73 는 scanf ( " %의 S " , STR + 1 ); 74 빌드 (tree_no, 1 , 1 , N); 75 빌드 (tree_yes, 1 , 1 , N); 76 DP [N] [ 1 ] = INF; DP [0 ] [ 0 ] = 0 ; (77) 에 대한이 ( int로 I = 1 ; i가 <N =; 내가 ++ ) { 78 의 경우 는 (i> 1 ) DP [I] [ 0 ] = 분 (DP [I - 1 ] [ 0 ] + I, 쿼리 (tree_yes, 1 , (1) N, 난 - 케이 I - 1 )); (79) 다른 DP [I] [ 0 ] = I; 80 업데이트 (tree_no, 1 , 1 , N, I, DP [I] [ 0 ]); 81 의 경우 (STR [I] == '1 ' ) { 82 경우 (전 - 케이 <= 1 ) DP [I] [ 1 ] = I; (83) 그 밖의 경우 (I> 1 ) DP [I] [ 1 ] = 분 (쿼리 (tree_yes, 1 , 1 , N, I - K i는 - 1 ), 84 쿼리 (tree_no, 1 , 1 , N, I - K - 1 , I - 1 )) + I; 85 업데이트 (tree_yes, 1 , 1 , N, I, DP [I] [ 1 ]); 86 } 87 } 88 의 printf ( " % LLD \ 없음 " , 분 (DP [N] [ 1 ], DP [N] [ 0 ])); 89 반환 0 ; 90 }
참고 블로그 : https://blog.csdn.net/qq_41730082/article/details/101119577