newoj 3311: Mixing Milk 混合牛奶【greedy】

题目描述
由于乳制品产业利润很低,所以降低原材料(牛奶)价格就变得十分重要。帮助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的牛奶制造公司拿到所需的牛奶所要的最小费用
样例输入
100 5
5 20
9 40
3 10
8 80
6 30
样例输出
630
分析:在01背包的分类里面,但是是一道贪心问题,注意事项见注释

/*int的范围-2147483648 ~ 2147483647 */
#include"stdio.h"
typedef struct str
{
    int cost;
    int  num;
}str;
void quicksort(str a[],int low,int high);

int main()
{
    int N,M,n,i;
    str f[5001];
    int ans = 0;
    scanf("%d%d",&N,&M);
    for(i = 1; i <=M; i++)
    {
        scanf("%d%d",&f[i].cost,&f[i].num);
    }
    quicksort(f,1,M);
    n = N;//用m来记录还需要的牛奶数 
/*  for(i = 1; i<=M;i++)//用来检验快排是否正确,发现如果函数中的中间变量temp不是str类型而是int类型,那么交换的只有价格,数量对应关系就乱了 
    printf("%d %d\n",f[i].cost,f[i].num);*/
    for(i = 1; i<=M&&n>0; i++)//在遍历已经排好序的牛奶的同时还要注意是否已经不再需要牛奶 
    {
        if(n >= f[i].num)
        {
            n -= f[i].num;//就把当前最便宜的牛奶全部都要
            ans += f[i].num*f[i].cost; 
        }
        else
        {
            ans += n*f[i].cost;
            n = 0;
        }
    }
    printf("%d",ans);
    return 0;
}
void quicksort(str a[],int low,int high)
{
    int i = low;
    int j = high;  
    str temp = a[i]; //只根据价格排序 但是中间变量要对应一个str单位,方便在后面交换价格的同时交换数量 

    if( low < high)
    {          
        while(i < j) 
        {
            while((a[j].cost >= temp.cost) && (i < j))
            { 
                j--; 
            }
            a[i].cost = a[j].cost;
            a[i].num = a[j].num;//注意在交换的时候一定要把对应的数量也交换 
            while((a[i].cost <= temp.cost) && (i < j))
            {
                i++; 
            }  
            a[j].cost= a[i].cost;
            a[j].num = a[i].num;//这里也是 
        }
        a[i].cost = temp.cost;
        a[i].num = temp.num;
        quicksort(a,low,i-1);
        quicksort(a,j+1,high);
    }
    else 
    return;

}

可以不自己写快排程序,重载STL中的sort的cmp函数即可。
对结构体中的某一个元素进行排列,同时其余元素也要跟着变化。注意cmp函数的写法。
sort()中写的是对结构体排序,但是cmp中真正决定大小的是其中的一个元素

#include<iostream>
#include<algorithm>
using namespace std;
struct milk{
    int p;
    int num;
};
milk m[5005];
int cmp(milk a,milk b)
{
    return a.p<b.p;
}
int N,M;
int main()
{
    cin>>N>>M;
    for(int i = 0;i<M;i++)
    {
        cin>>m[i].p>>m[i].num;
    }
    sort(m,m+M,cmp);
    int sum = 0;
    int n = N;
    for(int i = 0;i<M&&n!=0;i++)
    {
        if(m[i].num<n)
        {
            sum += m[i].num * m[i].p;
            n -=m[i].num;
        } 
        else 
        {
            sum += n * m[i].p;
            n = 0;
        } 

    }
    cout<<sum<<endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值