[古代遗产]洛谷题解 P1208 【[USACO1.3]混合牛奶 Mixing Milk】

本文写于2019.01.31


希望大家能够看懂!

此题我估计大多数人没做出来是因为木有思路?或者说不知怎么贪心

那么代码价值就不高了,我的代码和别人的大同小异。

我看了其他人的题解,好像都没有讲怎么贪心的。

那我就来结合实例讲讲吧!

1.回归小学

我们要从头开始,慢慢探索,不然看完仍然啥都不会!

假设我们需要10牛奶,题目给多个农民,我们先简化为两个。

每个农民的牛奶单价和卖的总量分别是

5 10

6 10

我们可以很快得出结论(50),就是直接买第一个农民的牛奶。
因为他的牛奶价格最少,并且他卖的总量够我们的需求!

2.稍加变化

我们把刚才的情况变一下,我们还要10牛奶,农民还是2个,但是每个农民的牛奶单价和总量分别是

5 5

6 10

我们会发现,用刚才的策略不行,因为最便宜的牛奶价格的农民的卖的总量不够我们的需求!,所以我们先全买光第一个农民的牛奶,再去买第二个农民的牛奶,只用买剩下需要的就行了!(55)。

3.回归题目

现在我们还是需要10牛奶,这次有仨农民,而这些农民的牛奶单价和总量分别是:

1 3

999 30

2 6

这次我们要这么买:首先按之前的规律我们就明白要先买第一个农民的,因为价格最便宜,买的不够就买次便宜的,也就是第三个农民的,还不够怎么办?再买次次便宜的!

---------------------------------------我是分割线---------------------------------------

综上所述,我们可以总结出如下规律:

先买最便宜的,如果没买够,再买次便宜的,如果还没买够,再买次次便宜的……

那么排序是要有的。

注意,不要出现下面情况:

……
int i,n,need,s=0;
cin>>n;
……
s=a[i]*need;
……

这是评测机的情况:

你:嘿,哥们,我还没买够那!

农民:我只有这么些牛奶!

你:那怎么办?

农民:凉拌!

这是你惊愕的面孔对着的:

WAWAWAWAWA~~~

所以,要写个while,来看看比较省时间的while是怎么写的:

#include<iostream>
#include<algorithm>
using namespace std;
struct AC {
	int price,total; 
} a[5010];
bool cmp(AC A,AC B){
	return A.price<B.price;
} //结构体排序
int main(){
	int i,n,need,s=0;
	//输入 
	cin>>need>>n;
	for(i=1; i<=n; i++)
		cin>>a[i].price>>a[i].total;
	//排序 
	sort(a+1,a+1+n,cmp);
	//拿牛奶 
	i=1;
	while(need!=0){ //如果没有买到足够的牛奶
		if(a[i].total>=need){//这些就够了?
			s=s+need*a[i].price;
			need=0;//嗯,看来是够了
        //这两句顺序不能换!
		}
		else {
			need=need-a[i].total;
			s=s+a[i].total*a[i].price;
			i++;//额,没够
		}
//		cout<<need<<" "<<s<<endl; 
	}
	//输出 
	cout<<s;
	return 0;
}
posted @ 2025-12-09 21:35  老子是北瓜  阅读(2)  评论(0)    收藏  举报