BZOJ 1150 데이터 백업

https://cn.vjudge.net/problem/HYSBZ-1150

이름

당신은 대형 사무실 건물이나 사무실 건물 백업을위한 컴퓨터 데이터 (사무실)와 같은 IT 회사입니다. 당신이 서로 사이에 다른 건물 상호 백업을 할 수 있도록 시스템을 설계 할 수 있도록 당신이 집에 앉아서 컴퓨터 게임의 재미를 즐길 동안 그러나, 데이터 백업은 지루한 작품은입니다. 알려진 사무실은 같은 거리에 있습니다. 당신은 페어링이 건물 (두 그룹)을 제공하기로 결정했다. 그들은 케이블 네트워크를 누워 두 건물 사이를 통과 할 수 있도록 건물의 각각은 서로 백업 할 수 있습니다. 그러나, 네트워크 케이블의 높은 비용. 현지 통신 회사는 당신이 단지 사무실 (또는 2K 사무실의 총) 스케줄 백업에 K에 할 수 있다는 것을 의미 K 케이블 네트워크를 제공 할 수 있습니다. 사무실 건물의 모든 쌍의 고유 한 (즉, 건물의 2K는 달라야합니다)에 속한다. 또한, 통신 회사는 네트워크 케이블의 길이 (킬로미터) 요금이 필요했다. 따라서, 당신은 가능한 한 짧게 케이블의 전체 길이를하게 사무실하는 K 선택해야합니다. 즉, 당신은 가능한 한 작게 각 사무실 건물의 쌍 (총 거리) 사이의 거리를 만들고, 사무실의 K를 선택해야합니다. 다음은 예입니다,도에서와 같이, 거리에서 사무실 건물 다섯 개 클라이언트를 가지고 가정합니다. 다섯 개 사무실은 높은 거리 1km, 3km, 4km, 6km와 12km 사무실에서 시작점에 위치하고 있습니다. 통신 회사는 K = 2 개 케이블을 제공합니다.

가장 좋은 예는 제 페어링 방식이며 연결된 제 사무실, 세 번째와 네 번째 빌딩에 접속된다. 따라서 K = 2 케이블의 사용을 요구할 수 있습니다. 제 1 케이블 길이 3km-= 1km 2km이고, 막대 (2)의 케이블 길이 6km-= 4km 2km이다. 이 방식은 4km 쌍 네트워크 케이블의 총 길이를 필요로하며, 최소 거리 요구 사항을 만족하고있다.

입력

첫 번째 행 N (2≤n≤100000)가 건물의 수를 나타내는 정수 n과 K를 포함 k는 (1≤k≤n / 2) 가능한 네트워크 케이블의 수를 나타낸다. 다음 n 줄은 시작 지점에서 거리에서 각 건물을 표현하는 하나의 정수 (0≤s≤1000000000)를 포함한다. 이 정수는 다시 작은에서 큰에 순서대로 표시됩니다.

산출

출력 양의 정수는, 필요한 네트워크 케이블의 뚜렷한 최소 총 길이 K에 연결된 2K 사무실을 제공하는 것이다.

샘플 입력

5 2 
1 
3 
4 
6 
12

샘플 출력

4

문제 해결

거리에 인접 탐욕 확실히 선택된 인접 바닥 따라서 선택된 개수 K가 최소 인접없는 번호의 무리로, 계산

방법이 고려했다

첫번째 최소 1 선택하고 나머지 시간은 작은 인접하지 않은 선택

2. 선거를 작은을 선택하지 마십시오 두 개의 인접한 다른 선택 최소로 +, 다른 옆에 확실히 좋지 않아 선택하지 않을 경우 +

 

돌아가려면, 당신은 가장 작은 수를 선택된다 선택할 수 있습니다 $ 오른쪽 + 왼쪽 - 자신의 $가 다음 선거 후 변경할 선거 인접한의 수에 해당

 

적층 이후 및 목록과 함께 넣어, 사용자가 컴퓨터 적층 수의 세트를 사용하여 힙 번호에 저장되어있는 데이터,리스트 번호 직접 후 착신 전화 번호 첨자 배열 Duixia를 열고

 

AC 코드

#INCLUDE <cstdio> 
#INCLUDE <cctype> 
#INCLUDE <알고리즘> 
#DEFINE REP위한 (R, X, Y) (INT의 R = (X)를 등록, R <(Y)를, R ++) 
#DEFINE REPE (R, X R <= (Y) (등록 INT의 R = (x)에 대한, Y) R ++) 
#ifdef와 sahdsg 
#DEFINE DBG (...)의 printf (__ VA_ARGS__) 
#else 
#DEFINE DBG (...) 보이드 (0 ) 
#endif 다음 
네임 스페이스를 사용하여 표준; 

_s를 int로; 문자의 _C; 
서식 <클래스 T> 
공극 리드 (T & X) { 
	X = 0; DO _c = getchar가 (); 동안 (! isdigit에 (_C) &&가 _C = '-'); _s = 1; 경우 (_c == '-') _s = -1, _c = getchar가 (); 반면 (isdigit에 (_C)) {X = X * 10 + _C-'0 '; _c = getchar가 ();} * X = S _; 
} 

#DEFINE MAXN 100,007 
#DEFINE MAXK 50007 

[MAXN] DT INT; 
INT 마력 [MAXN, SH;
[MAXN] 번째 INT //, TL [MAXN]; 

(INT 피)를 무효화 { 
	반면 (p> 1) { 
		경우 (DT [HP [P] <DT [HP [P >> 1]) { 
			스왑 (제 [HP [P], 제 [HP [ P >> 1]); 
			스왑 (HP [P] HP [P >> 1]); 
			p는 >> = 1; 
		} 다른 휴식; 
	} 
} 

아래 무효화 (INT의 P) { 
	INT S = P << 1; 
	반면 (S <= SH) { 
		경우 (S <SH && DT [HP [S + 1] <DT [HP [S]) (S) ++; 
		경우 (DT [HP [S] <DT [HP [P]) { 
			스왑 (제 [HP [P], 제 [HP [S]); 
			스왑 (HP [P] HP [S]); 
			P는 S 인; << S = 1; 
		} 다른 휴식; 
	} 
} 

공극 제거 (INT P는) { 
	HP [P] = HP [sh--]; 제 [HP [P] = P; 최대 (p); 다운 (p); 
} 

공극 LK (INT의 B, A INT) { 
	NXT는 [A]를 B =; 제 [B] A =; 
}

	N INT, K; (n)를 판독; (K)를 읽고; 
	INT 지금, LST; (LST) 판독; 
	REP (I, 1, n)은 { 
		(현재) 판독; INT의 t = 지금 LST; 지금 LST =; 
		DT [I]는 t =에; HP [SH ++] = 1; 제 [I]는 = 쉬; NXT [I] = 1 + 1, PRV [I] = I-1; 최대 (SH); 
	} 
	INT ANS = 0; 
	REP (C, 0, K) { 
		INT (X) = HP [1]; 
		ANS + DT = [X]; DBG ( "가 % d \ 없음!"DT [X]); 
		경우 (PRV [X] == 0 && NXT [X] == N) 분해; 
		만약 (! PRV [X] && NXT [X] = N) { 
			INT ND = DT [PRV의 [X] + DT [NXT [X] - DT [X]; 
			삭제 (제 [PRV의 [X]); 삭제 (제 [NXT [X]); LK (PRV [PRV [X], X); LK (X, NXT [NXT [X]); 
			삭제 (제 [X]); 
			DT [X] = ND; HP [++ SH =의 X; 번째는 [X] = SH가; 최대 (SH); 
		다른 경우} (PRV는 [X]) { 
			(제 [PRV [X]) 제거; NXT [PRV [PRV의 [X] = N; 
			삭제 (제 [X]);
		사용한다} else { 
			([X] [NXT] 번째)를 제거; PRV [NXT [NXT의 [X] = 0; 
			삭제 (제 [X]); 
		} 
	} 
	의 printf ( "% D \ 없음", ANS); 
}

 

추천

출처www.cnblogs.com/sahdsg/p/11244471.html