问题描述
牛奶包装是一个如此低利润的生意,以至于尽可能低地控制初级产品(牛奶)的价格变得十分重要。请帮助Merry的牛奶制造公司(Merry Milk Makers')以尽可能最廉价的方式取得他们所需的牛奶。Merry的牛奶制造公司从一些农民那购买牛奶,每个农民卖给牛奶制造公司的价格不一定相同。而且,如一只母牛一天只能生产一定量的牛奶,农民每一天只有一定量的牛奶可以卖。每天,Merry的牛奶制造公司从每个农民那购买一定量的牛奶,少于或等于农民所能提供的最大值。给出Merry牛奶制造公司的每日的牛奶需求,连同每个农民的可提供的牛奶量和每加仑的价格,请计算Merry的牛奶制造公司所要付出钱的最小值。
注意:每天农民生产的牛奶的总数对Merry的牛奶制造公司来说是足够的
格式
PROGRAM NAME: milk
INPUT FORMAT:file milk.in
第 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的牛奶制造公司的牛奶数量。
OUTPUT FORMAT:file milk.out
单独的一行包含单独的一个整数,表示Marry的牛奶制造公司拿到所需的牛奶所要的最小费用
SAMPLE INPUT
100 5 5 20 9 40 3 10 8 80 6 30
SAMPLE OUTPUT
630
解答:
方法1 :
将所有的牛奶按价格升序排列(用快排),然后从低到高买入,直到买够m为止。
贪心的证明:
假设某次买了价格稍高的牛奶,可以得到最优解。那么把这次买的牛奶换成价格更低的牛奶,其它不变,那么所得的解较优。假设不成立。
代码:
/*
ID: adreamo2
LANG: C++
TASK: milk
*/#include <cstdio>
#include <iostream>
#include <algorithm>using namespace std;
typedef struct _node {
int p;
int a;
} node;bool cmp(const node &e1, const node &e2){
return e1.p < e2.p;
}const int MAX_L = 5001;
node src[MAX_L];void solve(){
int N, M, i, ans = 0;
freopen("milk.in", "r", stdin);
freopen("milk.out", "w", stdout);
cin >> N >> M;
for(i = 0; i < M; ++i)
cin >> src[i].p >> src[i].a;
sort(src, src + M, cmp);
i = 0;
while(N > 0){
if(src[i].a < N){
ans += src[i].p * src[i].a;
N = N - src[i].a;
i++;
} else {
ans += src[i].p * N;
break;
}
}
cout << ans << endl;
}int main(){
solve();
//system("PAUSE");
return 0;
}
方法2 :
利用桶排的思想,因为价格的范围在1..1000之内,所以,我们只要在读入数据的时候把相同价格的合并即可,
进行计算时,也只需要for i:=0 to 1000 do进行扫描如果有价格为i的牛奶就收购即可,所以不需要排序。
代码:
/*
ID: adreamo2
LANG: C++
TASK: milk
*/#include <cstdio>
#include <iostream>
#include <algorithm>using namespace std;
const int MAX_L = 1001;
int array[MAX_L];void solve(){
int N, M, i, x, y, ans = 0;
freopen("milk.in", "r", stdin);
freopen("milk.out", "w", stdout);
cin >> N >> M;
for(i = 0; i < MAX_L; ++i)
array[i] = 0;
for(i = 0; i < M; ++i){
cin >> x >> y;
array[x] += y;
}
i = 0;
while(N > 0){
if(array[i] < N){
ans += array[i] * i;
N = N - array[i];
i++;
} else {
ans += i * N;
break;
}
}
cout << ans << endl;
}int main(){
solve();
//system("PAUSE");
return 0;
}