洛谷 P1090 [NOIP 2004 提高组] 合并果子

每次把最小两个堆合并即可。
题解都在用小根堆,但由于本菜鸡忘了小根堆stl创建方法,以及不想手写小根堆,因而转用multiset,也能过,复杂度大概是O(nlogn)

#include<iostream>
#include<set>
using namespace std;

int main(){
    multiset<int> s;  // 使用multiset允许重复元素
    int N, ans = 0;
    cin >> N;
    while(N--){
        int x;
        cin >> x;
        s.insert(x);
    }
    while(s.size() > 1){
        auto a = s.begin();
        int sum = *a + *(++a);
        s.erase(s.begin());
        s.erase(s.begin());
        ans += sum;
        s.insert(sum);
    }
    cout << ans;
    return 0;
}

补充手写的小根堆。。。这次码风有点问题,偷懒了。。

AcCode:

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int heap[10010], idx = 1;

void up(int index){
	if(heap[index] >= heap[index / 2] || index == 0) return ;
	swap(heap[index], heap[index / 2]);
	up(index / 2);
}

void insert(int v){
	heap[idx] = v;
	up(idx++);
}

void down(int index){
	int left = index * 2;
    int right = left + 1;
	if(left >= idx) return ;
    if(right < idx){
        if(heap[right] > heap[left] && heap[index] > heap[left]) swap(heap[left], heap[index]), down(left);
        else if(heap[right] < heap[index]) swap(heap[right], heap[index]), down(right);
    }else if(heap[index] > heap[left]) swap(heap[left], heap[index]), down(left);  
}

void pop(){
	heap[1] = heap[--idx];
	down(1);
}

int top(){
	return heap[1];
}
int main(){
	int N, ans = 0;
	cin >> N;
    int m = N;
	while(N--){
		int x;
		cin >> x;
		insert(x);
	}
	for(int i = 1; i < m; i++){
        int a = top();
        pop();
        int b = top();
        pop();
        ans += a + b;
        insert(a + b);
    }
    cout << ans;
    return 0;
}
posted @ 2025-05-28 21:42  Yuhhhhh  阅读(22)  评论(0)    收藏  举报