• 洛谷p1208—混合牛奶【典型贪心】(关联排序小技巧)


    今天做贪心题时遇到了之前就好几次难住我的小问题,对于有关联的两组数据,按照其中一组优先的方法排序,在做完这道题时想要记录下来自己的想法,以备后来可以遇到相同的问题时可以来查询~

    先把题目列出来:

    题目描述

    由于乳制品产业利润很低,所以降低原材料(牛奶)价格就变得十分重要。帮助Marry乳业找到最优的牛奶采购方案。

    Marry乳业从一些奶农手中采购牛奶,并且每一位奶农为乳制品加工企业提供的价格是不同的。此外,就像每头奶牛每天只能挤出固定数量的奶,每位奶农每天能提供的牛奶数量是一定的。每天Marry乳业可以从奶农手中采购到小于或者等于奶农最大产量的整数数量的牛奶。

    给出Marry乳业每天对牛奶的需求量,还有每位奶农提供的牛奶单价和产量。计算采购足够数量的牛奶所需的最小花费。

    注:每天所有奶农的总产量大于Marry乳业的需求量。

    输入输出格式

    输入格式:

    第 1 行共二个数值:N,(0<=N<=2,000,000)是需要牛奶的总数;M,(0<= M<=5,000)是提供牛奶的农民个数。

    第 2 到 M+1 行:每行二个整数:Pi 和 Ai。

    Pi(0<= Pi<=1,000) 是农民 i 的牛奶的单价。

    Ai(0 <= Ai <= 2,000,000)是农民 i 一天能卖给Marry的牛奶制造公司的牛奶数量。

    输出格式:

    单独的一行包含单独的一个整数,表示Marry的牛奶制造公司拿到所需的牛奶所要的最小费用。

    我们从题目里便可以看出来,这道题是非常典型的贪心算法,只需要把这些数据进行排序,这道题是按照价格优先的顺序来排序,最后只需要一点点加上价格便可以得到结果

    自己整理一点排序算法:需求:假设有两组数据,互相有关联(判定需要用结构体),此时需要按照其中一组优先(另一组次优)来排序

    例题:
    混合牛奶(背包问题)
    先按照单价排序,单价小的在前面,单价一样的就把产量多的放前面

    先写结构体:
    typedef struct node
    {
    int a,b;//定义单价和产量
    }MILK;

    再写比较函数:
    bool cmp(node x,node y)
    {
    return x.a<y.a;
    }

    还有一种写法:
    bool cmp(node x,node y)
    {
    if(x.a!=y.a) return x.a<y.a;
    else return x.b>y.b;
    }//但是我认为没有必要,由于单价相同,选择谁便没有必要

    关键来了!
    如何排序:
    在main函数中写:
    MILK people[5005];
    sort(people,people+m,cmp);//个人猜测这里cmp代表自己定义的排序函数

    这里最重要的一点是明白了可以自己写sort函数中的比较函数cmp!!划重点呦~~

    直接上AC代码吧:

    /*
    *问题思考:由于每次买牛奶时可以选择不买全部的牛奶,
    *从而思考可以采用贪心算法求解
    */
    
    #include <bits/stdc++.h>
    
    using namespace std;
    
    typedef struct node
    {
        int price;//定义价格
        int mount;//定义产量
    }MILK;
    
    bool cmp(MILK m1,MILK m2)
    {
        if(m1.price!=m2.price) return m1.price<m2.price;
        else return m1.mount>m2.mount;
    }
    
    int main()
    {
        MILK people[5005];
        //这里由于人数最多5000,所以开一个5005的结构体数组
        int N,M;
        //N代表需要牛奶总数,M代表农民个数
        cin >> N >> M;
        int P,A;
        //P代表牛奶单价,A代表牛奶数量
        //这道题需要按照牛奶价格排序
        for(int i=0; i<M; i++)
        {
            cin >> P >> A;
            people[i].price=P;
            people[i].mount=A;
        }
        sort(people,people+M,cmp);//这里;利用了快排的函数,真的巧妙
        /*cout << endl;
        for(int i=0;i<M;i++)
        {
            cout << people[i].price << ' ' << people[i].mount << endl;
        }*/
        //现在开始计算牛奶数量
        int index=0;
        int money=0;
        while(N>0)
        {
            if(N>=people[index].mount)
            {
                N-=people[index].mount;
                money+=(people[index].mount*people[index].price);
            }
            else
            {
                money+=(N*people[index].price);
                N=0;
            }
            index++;
    
        }
        cout << money << endl;
        return 0;
    }

  • 相关阅读:
    文件内容排名算法,输入排名函数,返回排名后的文件名
    线段树做大数据排序
    给字符排序-基类排序二分查找-JavaScript
    后缀数组、名次数组-JavaScript
    二分查找法、二分去重排序法,返回最接近的位置和实际位置
    用四叉树对图像分类,获取tag和key
    Linux显示所在Git分支
    Linux中设置Git显示颜色
    屏蔽网页广告
    tf.add_to_collection,tf.get_collection简介
  • 原文地址:https://www.cnblogs.com/ever17/p/11213176.html
Copyright © 2020-2023  润新知