洛谷P1208混合牛奶 Mixing Milk

题目描述

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

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

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

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

输入格式

第一行二个整数 n,m表示需要牛奶的总量,和提供牛奶的农民个数。

接下来 m 行,每行两个整数 pi​,ai​,表示第 i个农民牛奶的单价,和农民 i一天最多能卖出的牛奶量。

输出格式

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

输入输出样例

输入 #1复制

100 5
5 20
9 40
3 10
8 80
6 30

输出

630

说明/提示

【数据范围】
对于 100% 的数据:
0<=n,ai​≤2×10^6,50000≤m≤5000,10000≤pi​≤1000

标签时贪心,这道题目不算难,题目中话比较多,这里简单介绍一下。就是一个公司每天需要牛奶,有一些农民会提供一定量的牛奶,每一定数量的牛奶有对应的单价,这里我们要计算每天满足公司需求所花的钱最少。

这里就拿题目所给的例子举例子假设需要100的牛奶,首先我们应当找到单价最低的,然后买完,也就是3元的  买10个,现在离总量还差90个,所以我们再取第二单价低的,也就是5 元的,总共有20个,现在距离公司需求还差70,现在买6元的,总共有30个,现在还差40个。现在最低了只有8元的了,现在还差40个,但是8元的牛奶提供了80个牛奶,这里我们只需要买40个就行了。

那么这边我们应该如何在着一些农民中找到单价最小的人呢,这里我们可以使用排序,从小到大排序即可。这里每个农民相当于有两个属性,一个是单价,另一个是卖出的牛奶数量。这里我们就可以使用结构体

分析到这里就结束了,现在开始coding

先创建农民结构体

struct farmer {
	int money;//单价
	int num;//数量
};

现在读取数据并且创建一个结构体数组来储存这些农民

struct farmer peo[5010];
	int n, m;
	cin >> n >> m;
	for (int i = 0; i < m; i++) {
		cin >> peo[i].money >> peo[i].num;
	}

现在我们就需要排序了,这里我们可以使用c++自带的sort排序,不过我们需要写sort的排序条件

sort(peo, peo + m, cmp);
bool cmp(struct farmer A, struct farmer B) {
	return A.money < B.money;
}

这里的判断条件是从小到大排序,然后我们应该以农民提供的单价进行排序。

我们现在需要挑价格低的农民先开始购买他们的牛奶

	int sum = 0 , allmoney = 0 , i = 0;
	while (sum < n) {
		if (sum + peo[i].num <= n) {
			sum += peo[i].num;
			allmoney += peo[i].money * peo[i].num;
			i++;
		}
		else {
			allmoney += (n - sum) * peo[i].money;
			sum = n;
		}
	}

最后输出即可。

这里我把全部代码放出来可供大家参考

#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;
struct farmer {
	int money;//单价
	int num;//数量
};
bool cmp(struct farmer A, struct farmer B) {
	return A.money < B.money;
}
struct farmer peo[5010];
int main() {
	int n, m;
	cin >> n >> m;
	for (int i = 0; i < m; i++) {
		cin >> peo[i].money >> peo[i].num;
	}
	sort(peo, peo + m, cmp);
	int sum = 0 , allmoney = 0 , i = 0;
	while (sum < n) {
		if (sum + peo[i].num <= n) {
			sum += peo[i].num;
			allmoney += peo[i].money * peo[i].num;
			i++;
		}
		else {
			allmoney += (n - sum) * peo[i].money;
			sum = n;
		}
	}
	cout << allmoney;
	return 0;
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值