[古代遗产]洛谷题解 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;
}

浙公网安备 33010602011771号