問題の説明
あなたは、IT企業は、大規模なオフィスビルやオフィスビルなどのバックアップのためのコンピュータデータの(事務所)です。しかし、データのバックアップは面倒な作業ですので、自宅で座って、コンピュータゲームの楽しさを楽しみながら、あなたは、お互いの間で異なる構築相互バックアップを許可するようにシステムを設計します。
既知のオフィスは同じ通りに位置しています。あなたはペアリングこれらの建物(2グループ)を与えることにしました。それらはケーブルネットワークを敷設これら二つの建物の間を通過できるように、建物のそれぞれは、互いにバックアップすることができます。
しかし、ネットワークケーブルのコストが高いです。ローカル通信会社だけが唯一のオフィス(または2Kオフィスの合計)スケジュールバックアップにKにできることを意味Kケーブルネットワーク、を提供することができます。オフィスビルの任意のペアの固有のセット(つまり、建物の2Kが異なっていなければならない)に属しています。
また、テレコム会社は、ネットワークケーブルの長さ(キロメートル)の電荷が必要でした。したがって、あなたはできるだけ短いケーブルの長さの合計を作るオフィス向けたK選択する必要があります。言い換えれば、あなたは、各オフィスビルの組となるべく小さい(総距離)の間の距離を作り、事務所のKを選択する必要があります。
ここでは一例だ、図に示すように、あなたは、ストリートのオフィスビルの5台のクライアントを、持っていると仮定します。5つの事業所は、ハイストリート1キロ、3キロ、4キロ、6キロと12キロオフィスからの出発点に位置しています。テレコム会社はK = 2本のケーブルを提供します。
最良の例では、最初のペアリング方式であり、接続された第二の局は、第三及び第四の建物に接続されています。従ってK = 2は、ケーブルの使用を必要とすることができます。第1条のケーブルの長さは3キロ、1キロ= 2キロで、バー2のケーブルの長さは6キロ、4キロ= 2キロです。この方式は、4キロペアネットワークケーブルの全長を必要とし、最小距離要件を満たします。
入力形式
入力ファイルの最初の行は、nは(1≤n≤100000)建物の数を示す整数nとkを含んで、kは(1≤k≤n/ 2)利用可能なネットワークケーブルの数を表します。
次のn行単一の整数(0≤s≤1000000 000)が含まれ、それは出発点で通りに各オフィスの距離を表します。これらの整数は、今度は小から大への順序で表示されます。
出力フォーマット
出力ファイルも必要なケーブルのネットワークを構築するKに2Kの異なる最小全長与えられ、正の整数でなければなりません。
サンプル入力
5 2
1
3
4
6
12
サンプル出力
4
データ範囲
入力データ満たすn≤2030%。
入力データ満足の60%n≤10000
解決
貪欲考えてみましょう。1つの明白な結論は良くなることができない建物の数、全体に接続することは不可能です。だから、そのような貪欲な戦略があります:あなたが最短で隣接する点を選択し、ルートの両側にマークを付けるたびにオプションではありません。もちろん、これはどちらかの側に大きな損失をもたらすことを選択しない場合も、右ではありません。後の影響を排除する方法はありますか?
ここで使用される方法は、意思決定に戻って参加します。辺の長さの組を削除\(L_iを\) 、その後、両側の長さである\(I-メントキシ1}を{\)、\ (+ {Iが\メントキシ1}) 。我々が選択したとき\(L_iを\) 、削除\(I-メントキシプロパンを1} {\)、\ (メントキシ1} + {私は\)を添加しながら、\(L_ {I-1} + L_ {iは、+ 1 } -l_i \) Repentantlyを選択します。このように、我々は正しい決定を確保することができます。
それは隣接する点の変化に関係するように、我々は、このプロセスのヒープの実装を追加するために、リストを使用することができます。
コード
#include <iostream>
#include <cstdio>
#include <queue>
#define int long long
#define N 200002
using namespace std;
priority_queue<pair<int,int> > q;
int n,k,i,pre[N],nxt[N],d[N],a[N],ans,cnt;
bool vis[N];
int read()
{
char c=getchar();
int w=0;
while(c<'0'||c>'9') c=getchar();
while(c<='9'&&c>='0'){
w=w*10+c-'0';
c=getchar();
}
return w;
}
signed main()
{
n=read();k=read();
for(i=0;i<n;i++){
a[i]=read();
if(i>=1){
d[i]=a[i]-a[i-1];
q.push(make_pair(-d[i],i));
pre[i]=i-1;nxt[i]=i+1;
}
}
d[0]=d[n]=1<<30;
for(i=1;i<=k;i++){
while(!q.empty()){
int x=q.top().second,dis=-q.top().first;
q.pop();
if(vis[x]) continue;
ans+=dis;
vis[pre[x]]=vis[nxt[x]]=1;
d[x]=d[pre[x]]+d[nxt[x]]-d[x];
q.push(make_pair(-d[x],x));
nxt[pre[pre[x]]]=x;
pre[nxt[nxt[x]]]=x;
pre[x]=pre[pre[x]];
nxt[x]=nxt[nxt[x]];
break;
}
}
printf("%lld\n",ans);
return 0;
}