【codevs1245】最小的N个和

problem

solution

codes

//动态维护大根堆,贪心减少入队元素个数
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn = 100010;
int n, a[maxn], b[maxn];
//q为答案的n个元素。
priority_queue<int>q;
//递归输出
void print(){
    if(q.empty())return ;
    int t = q.top();  q.pop();
    print();
    cout<<t<<" ";
}
int main(){
    cin>>n;
    for(int i = 1; i <= n; i++)cin>>a[i];
    for(int i = 1; i <= n; i++)cin>>b[i];
    //step1:排序,让序列单调,后面用单调性减少状态数
    sort(a+1,a+n+1);
    sort(b+1,b+n+1);
    //step2:随便加n个元素作为初始值
    for(int i = 1; i <= n; i++){
        q.push(a[1]+b[i]);
    }
    for(int i = 2; i <= n; i++){
        if(a[i]+b[1]>=q.top())break;//step3因为单调,所以后面的a[i]+b[1]只会更大。
        for(int j = 1; j <= n; j++){
            if(a[i]+b[j]>=q.top())break;//step4:因为单调,所以后面的肯定会更大。
            //step5:如果没有break,则当前元素比答案中的最大值要大,更新答案。
            q.pop();
            q.push(a[i]+b[j]);
        }
    }
    //step6:此时队列中剩下的n各元素就是最小值
    print();
    return 0;
}
posted @ 2018-06-01 21:30  gwj1139177410  阅读(194)  评论(0)    收藏  举报
选择