贪心算法

万里不惜死,一朝得成功

区间选点

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>

using namespace std;

bool compareb(pair<int,int> &a, pair<int,int> &b){
    return a.second < b.second;
}
// 贪心算法
int main()
{
    int n;
    cin >> n;
    vector<pair<int,int>> A(n);
    for (int i = 0; i < n; i ++ ){
        cin >> A[i].first >> A[i].second;
    }
    sort(A.begin(), A.end(), compareb);
    
    int res = 1;
    int lastr = A[0].second;
    int l,r;
    // 排序后,不断遍历,如果这次的左小于上次的右就还可以有交点,如果大于就+1然后更新右
    for (int i = 1 ; i < n; i ++ ){
        l = A[i].first;
        r = A[i].second;
        if(l > lastr){
            res ++;
            lastr = r;
        }
    }
    cout << res;
    return 0;
}

最大不相交区间

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;


bool compareb(pair<int,int> &a, pair<int,int> &b){
    return a.second < b.second;
}

int main()
{
    int n;
    cin >> n;
    vector<pair<int,int>> A(n);
    for (int i = 0; i < n; i ++ ){
        cin >> A[i].first >>A[i].second;
    }
    sort(A.begin(),A.end(),compareb);
    int res = 1;
    int lastr = A[0].second;
    int l,r;
    //类似选点
    for (int i = 1; i < n; i ++ ){
        l = A[i].first;
        r = A[i].second;
        if(l > lastr){
            res ++;
            lastr = r;
        }
    }
    cout << res;
    return 0;
}

区间分组

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;


bool compareb(pair<int,int> &a, pair<int,int> &b){
    return a.first < b.first;//这次是用起点排序
}

int main()
{
    int n;
    cin >> n;
    vector<pair<int,int>> A(n);
    for (int i = 0; i < n; i ++ ){
        cin >> A[i].first >>A[i].second;
    }
    sort(A.begin(),A.end(),compareb);
    int res = 0;
    int lastr = -1e9-1;
    int l,r;
    vector<bool> visit(n,false);
    for (int j = 0; j < n; j ++ ){
        if(!visit[j]){//如果尚未记录就可以走
            visit[j] = true;
            res++;
            lastr = A[j].second;
            for (int i = j+1; i < n; i ++ ){
                if(!visit[i]){
                    l = A[i].first;
                    r = A[i].second;
                    if(l > lastr){
                        lastr = r;
                        visit[i] = true;
                    }
                }
            }
        }
    }
    cout << res;
    return 0;
}

自己写了一个超时方法。
优化了一下还是不行

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;


bool compareb(pair<int,int> &a, pair<int,int> &b){
    return a.first < b.first;//这次是用起点排序
}

int main()
{
    int n;
    cin >> n;
    vector<pair<int,int>> A(n);
    for (int i = 0; i < n; i ++ ){
        cin >> A[i].first >>A[i].second;
    }
    sort(A.begin(),A.end(),compareb);
    int res = 0;
    int lastr = -1e9-1;
    int l,r;
    vector<bool> visit(n,false);
    int j = 0;
    bool flag = true;
    while(j<n){//实际上O(n)?
        flag = true;//确保每次更新的都是最小的那个非同区间
        if(!visit[j]){//如果尚未记录就可以走
            visit[j] = true;
            res++;
            lastr = A[j].second;
            for (int i = j+1; i < n; i ++ ){
                if(!visit[i]){
                    l = A[i].first;
                    r = A[i].second;
                    if(l > lastr){
                        lastr = r;
                        visit[i] = true;
                    }else if(flag){
                        j = i;
                        flag = false;
                    }
                }
            }
        }else{
            j++;
        }
    }
    cout << res;
    return 0;
}

区间分组

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>

using namespace std;

int main()
{
    int n;
    cin >> n;
    vector<pair<int,int>> A(n);
    for (int i = 0; i < n; i ++ ){
        cin >> A[i].first >> A[i].second;
    }
    sort(A.begin(), A.end());
    // greater反过来是less
    priority_queue<int, vector<int>, greater<int>> min_heap;
    int l,r;
    for (auto x: A){
        l = x.first;
        r = x.second;
        if(!min_heap.empty()&&min_heap.top()< l){
            min_heap.pop();//因为是经过排序的,如果l比上一个r大,说明不是相交的一组
            //那么把他弹出换成现在的r,才能正确下一次比较
        }
        min_heap.push(r);
    }
    cout << min_heap.size();
    return 0;
}

区域覆盖

#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>

using namespace std;
typedef pair<int,int> PII;

bool compareb(PII&a,PII&b){
    return a.second < b.second;
}

int main()
{
    PII tar;
    cin >> tar.first >> tar.second;
    int n;
    cin >> n;
    vector<PII> A(n);
    int a,b;
    for (int i = 0; i < n; i ++ ){
        cin >> a >> b;
        if(a>tar.second||b<tar.first)continue;
        A[i].first = a;
        A[i].second = b;
    }
    sort(A.begin(), A.end());
    
    //当前区间
    int len = A.size();
    int maxs = tar.first;
    int curs = tar.first;
    int i = 0;
    int res = 0;
    //贪心算法
    while(curs < tar.second){//用这个保证再循环捏判断
        while(i<len&&A[i].first<=curs){//数组不越界,更新边界
            maxs = max(maxs, A[i].second);
            i++;
        }
        if(curs == maxs){//maxs无法更新,说明没了
            cout << -1;
            return 0;
        }
        curs = maxs;//突破了边界,进入下一个边界
        res ++;
        if(curs >= tar.second){//相等边界
            cout << res;
            return 0;
        }
    }
    for(auto x:A){//针对单点的情况
        int a = x.first;
        int b = x.second;
        if(a<=tar.first&&b>=tar.second){
            cout << 1;
            return 0;
        }
    }
    //都不能就没了
    cout << -1;
    return 0;
}

哈夫曼树

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>

using namespace std;


int main()
{
    int n;
    cin >> n;
    vector<int> A(n);
    for (int i = 0; i < n; i ++ ){
        cin >> A[i];
    }
    sort(A.begin(),A.end());
    int temp;
    long long sum = 0;
    while(A.size()>1){
        A[0] = A[0] + A[1];
        sum += A[0];
        auto it = A.erase(A.begin()+1);
        sort(A.begin(),A.end());
    }
    cout << sum;
    return 0;
}


第一个做法,每次加完就排序。
还有一个小根堆做法。

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>


using namespace std;


int main()
{
    int n;
    cin >> n;
    int a;
    
    //最小堆
    priority_queue<int, vector<int>, greater<int>> min_heap;
    for (int i = 0; i < n; i ++ ){
        cin >> a;
        min_heap.push(a);
    }
    int x,y;
    int sum = 0;
    while(min_heap.size()>1){
        x = min_heap.top();
        min_heap.pop();
        y = min_heap.top();
        min_heap.pop();
        x = x + y;
        sum += x;
        min_heap.push(x);
    }
    cout << sum;
    return 0;
}

    

排队打水

#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>

using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
typedef unsigned long long ULL;

int main()
{
    int n;
    cin >> n;
    int a;
    priority_queue<int, vector<int>, greater<int>> h;
    for (int i = 0; i < n; i ++ ){
        cin >> a;
        h.push(a);
    }
    long long sum = 0;
    int x,t=0;
    while(h.size()>0){//注意这里是排队打水获得等待时间
        x = h.top(); h.pop();
        sum += t;
        t += x;
    }
    cout << sum;
    return 0;
}

仓库选地址

#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
//多组数据要清空
using namespace std;

int main()
{
    int n;
    cin >> n;
    vector<int> A(n);
    for (int i = 0; i < n; i ++ ){
        cin >> A[i];
    }
    vector<int> B = A;
    sort(A.begin(), A.end());
    // 找中位数~
    int mid;
    if(n % 2 == 0){
        mid = A[n/2]+A[(n/2) - 1];
        mid /= 2;
    }else{
        mid = A[n/2];
    }
    int sum = 0;
    for (int i = 0; i < n; i ++ ){
        sum += abs(mid - B[i]);
    }
    cout << sum;
    return 0;
}

堆牛

#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>

//注意预设负无穷正无穷,数据复杂!
//注意使用longlong!!
//明天整理板子

using namespace std;
typedef pair<int, int> PII;
// 重的和承重厉害的都应该在下面,直接加起来不就好了。。
bool compareb(PII&a,PII&b){
    return a.second+a.first > b.second+b.first;
}

int main()
{
    int n;
    cin >> n;
    vector<PII> A(n);
    for (int i = 0; i < n; i ++ ){
        cin >> A[i].first >> A[i].second;
    }
    sort(A.begin(), A.end(), compareb);
    // 题目还要求是必须是最大值。。要注意题目啊
    int maxe = -0x3f3f3f3f;//预设用这个才对
    
    for (int i = 0; i < n; i ++ ){
        int weight = 0;
        for (int j = i+1; j < n; j ++ ){
            weight += A[j].first;
        }
        maxe = max(maxe, weight - A[i].second);
    }
    
    cout <<maxe<<endl;
    
    return 0;
}
posted @ 2025-09-01 21:35  .N1nEmAn  阅读(17)  评论(0)    收藏  举报