アルゴリズム4.3香港ニマとマンゴーバスケットの設計と解析

★タイトル説明

マンゴーのn個のバスケットの合計は、あるI-バスケットマンゴーをaiを。

企業は、李、里、あなたがk個の間隔を選択する必要がありますすることができますメートル間隔の選択肢を与えています

ドルにすることができるすべての市販のkに対応するこれらの間隔の交点の位置にマンゴー。

香港ニマただ唯一のドルは、彼はマンゴーの最大数は、このお金で買うことができます知りたいですか?

★入力フォーマット

最初の3つの正の整数の動作N、K、Mは、マンゴーバスケットの数を表し、間隔の合計数の数は、セグメントを選択するために必要と選択されてもよいです。

2行目は各バスケットマンゴーの数を表すnは正の整数を含んでいます。

2つの正の整数の次のmラインのLi、RI、選択することができる間隔を表します。

データの60%、1 <= N <= 103,1 <= K <= M <= 103。

对于100%的数据、1 <= N <= 105,1 <= K <= M <= 105,0 <= aiを<= 109,1 <=リー<= RI <= nです。

★出力形式

マンゴーの最大数を表す正の整数を出力します。

★サンプル入力

5 2 4
1 2 3 4 5
1 2
2 3
3 4
2 5

★サンプル出力

★ヒント

ノー

★参照コード

/*
本题是区间的并集查找 

先按照左端点从小到大对区间排序
然后将前k个区间的右端点放入最小优先队列中
此时这k个区间的并集为【第k个区间的左端点(因为左端点依据排序了),优先队列中最小的右端点】 
那么就可以得到这k个区间的芒果数

接站遍历区间 
不断的删除优先队列中最小右端点,加入新区间的右端点 
*/
#include<bits/stdc++.h>
using namespace std;

int n,k,m;
int sum[100005] = {0};
struct section{
    int l,r;
    section() {}
    section(int v1, int v2):l(v1),r(v2){}
    bool operator < (const section &b) const{return l==b.l ? r<b.r : l<b.l;}
}S[100005];

int main(){
    scanf("%d%d%d",&n,&k,&m);
    
    int a;
    for(int i=1; i<=n; ++i) scanf("%d",&a), sum[i] = sum[i-1]+a;
    for(int i=1; i<=m; ++i) scanf("%d%d",&S[i].l, &S[i].r);
    
    sort(S+1, S+m+1);
    
    int res=0;
    priority_queue<int, vector<int>, greater<int> > q;
    for(int i=1; i<=m; ++i){
        q.push(S[i].r);
        if(q.size()==k){
            res = max(res, sum[q.top()]-sum[S[i].l-1]);
            q.pop();
        }
    }
    
    printf("%d\n",res);
    return 0;
} 

おすすめ

転載: www.cnblogs.com/yejifeng/p/12075646.html