[BZOJ1150] CTSC2007] 데이터 백업

제목 설명

당신은 수 있습니다 \ (IT \) 사무실 건물 또는 사무실 건물 대형 컴퓨터 데이터의 백업을 수행하는 회사입니다. 당신이 서로 사이에 다른 건물 상호 백업을 할 수 있도록 시스템을 설계 할 수 있도록 당신이 집에 앉아서 컴퓨터 게임의 재미를 즐길 동안 그러나, 데이터 백업은 지루한 작품은입니다. 알려진 사무실은 같은 거리에 있습니다. 당신은 페어링이 건물 (두 그룹)을 제공하기로 결정했다. 그들은 케이블 네트워크를 누워 두 건물 사이를 통과 할 수 있도록 건물의 각각은 서로 백업 할 수 있습니다. 그러나, 네트워크 케이블의 높은 비용.

단지 당신을 제공 할 수있는 지역 통신 회사 \ (K \) 즉, 케이블 네트워크를 제거 할 수 있습니다에만 \ (K \) 사무실 (또는 총의 \ (2K \) 건물) 스케줄 백업. 사무실 건물의 모든은 (즉, 쌍의 고유 한 세트에 속하는 \ (2K \) 반드시 사무실 일 별개). 또한, 통신 회사는 네트워크 케이블의 길이 (킬로미터) 요금이 필요했다.

따라서, 당신이 그것을 선택해야합니다 \ (K \) 사무실을되도록 가능한 한 짧게 케이블의 총 길이. 즉, 당신은 그것을 선택해야합니다 \ (K \) , 사무실 건물을 가능한 한 작은 사무실과 (총 거리) 사이의 거리의 각 있도록.

다음의 예는, 당신이 한 가정 (5 \) \ 그의 사무실 거리에있는 고객을. 그것은 \ (5 \) 스트리트 사무소는 시작점에서있는 번째 \ (1km, 3km, 4km, 6km \) 와 \ (12km \) 에서. 통신 회사는 당신을 제공합니다 \ (K = 2 \) 케이블.

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

입력

입력의 첫 번째 라인은 정수 포함 \ (\ N-)\ (K \) 여기서 \ (N (2 \ 르 N \ 르 100,000) \) 건물의 수를 나타내는 \ (K는 \) 가능한 네트워크를 나타낸다 케이블의 수.

다음 n 줄은 하나의 정수 $를 포함 (0 \ 르의 \ 르 1,000,000,000) $는 각각 거리까지의 거리의 시작에 건물을 나타냅니다.

이 정수는 다시 작은에서 큰에 순서대로 표시됩니다.

산출

출력해야 주어진 양의 정수, \ (2K \) 로 연결된 서로 다른 사무실 \ (K \) 에 필요한 네트워크 케이블의 최소 총 길이.

샘플 입력

5 2 
1
3
4
6
12

샘플 출력

4

당신은 욕심에 다시 갈 수 있습니다! ! !

문제의 표면을 참조하십시오, 당신이 사무실의 전체 회로를 받아보실 수 있습니다 것이 분명
하고, 인접한 사무실 건물 연결됩니다.

힙을 유지하기 위해 자연입니다.

여부가 제거 된 라인을 고려하지 않은 힙의 상단 될 수있는 시간이며, 마킹?

당신은 샘플에서 볼 수있는이 작동하지 않습니다. .

어떻게 그것을 할까?

그래서 우리는 프로그램에게 "후회"기회를 제공 : 함께 거리 두 사무실 건물의 거리 인 한 쌍으로 건물의 양쪽에있는 팝업 - 사무실에서 팝업.

그래서 우리는 동등한 마이너스 양쪽의 중간이 시간이 걸릴 다음 걸릴에 "후회"과정이 그것입니다!

체인의 양측 유지가 달성 될 수있다.

주의는 변수의 비워해야한다;

다음 코드는

#include<bits/stdc++.h>
using namespace std;
#define reg register
#define rep(a,b,c) for(reg int a=(b),a##_end_=(c); a<=a##_end_; ++a)
#define drep(a,b,c) for(reg int a=(b),a##_end_=(c); a>=a##_end_; --a)
#define debug(x) cerr<<#x<<" = "<<x<<endl;
int Read() {
    int res=0,f=1;
    char c;
    while(c=getchar(),c<48)if(c=='-')f=-1;
    do res=(res<<3)+(res<<1)+(c^48);
    while(c=getchar(),c>=48);
    return res*f;
}
void Min(double &A,double B) {
    if(A>B)A=B;
}
const int M=1e5+5;
int n,k,Ans,A[M],S[M],L[M],R[M];
bool vis[M];
void Add(int num) {
    L[num]=num-1,R[num]=num+1;
}
void Del(int num) {
    vis[num]=1;
    L[R[num]]=L[num];
    R[L[num]]=R[num];
}
struct node {
    int id;
    bool operator<(node _)const {
        return S[id]>S[_.id];
    }
};
priority_queue<node>Q;
int main() {
    n=Read(),k=Read();
    rep(i,1,n)A[i]=Read(),L[i]=i-1,R[i]=i+1;
    rep(i,1,n-1) {
        S[i]=A[i+1]-A[i];
        Q.push((node)<%i%>);
    }
    S[0]=S[n]=1e9;
    rep(i,1,k){
        node Now=Q.top();
        Q.pop();
        if(vis[Now.id]) {
            i--;
            continue;
        }
        Ans+=S[Now.id];
        S[Now.id]=S[L[Now.id]]+S[R[Now.id]]-S[Now.id];
        Del(L[Now.id]),Del(R[Now.id]);
        Q.push((node)<%Now.id%>);
    }
    printf("%d",Ans);
}

추천

출처www.cnblogs.com/dsjkafdsaf/p/11279414.html