题解 P1208 【[USACO1.3]混合牛奶 Mixing Milk】
貌似大家都在用快排啊
其实选择排序就能过
本人亲测
就在这里
——————————————(切入正题)————————————————
思路:排序+贪心
其实一开始看到题目时以为是背包,没办法,我太蒟了
既然是计算最小花费,那么就肯定是优先选择单价最便宜的
(貌似这句话是废话)
那单价一样的怎么办?
答曰:优先选择提供牛奶最多的
why?
排序结束后,就按照单价从小到大的顺序直接模拟,如果把产量最多的放前面,更省时
直接放代码
#include<bits/stdc++.h>//万能头(不过楼下好像不推荐)
using namespace std;
long long m,n;
long long p[5001],a[5001];
long long t,tt;
long long sum,ans;
//其实完全没有必要开long long,开了还占内存,但是在内存足够的情况下,更保险
int main()
{
cin>>m>>n;
//scanf("%lld%lld",&m,&n);
//但是用cin也不会超时
if(m==0)
{
cout<<"0"<<endl;
return 0;
}
//这个特判一定要!如果需求为零,干嘛要买
//我就被坑过QAQ
for(int i=1;i<=n;i++)cin>>p[i]>>a[i];
for(int i=1;i<=n;i++)
{
t=i;
for(int j=i+1;j<=n;j++)
{
if(p[t]>p[j])t=j;
if(p[t]==p[j])
{
if(a[t]<a[j])t=j;
}
}
if(t!=i)
{
tt=p[i];p[i]=p[t];p[t]=tt;
tt=a[i];a[i]=a[t];a[t]=tt;
}
}
//以上是选择排序
for(int i=1;i<=n;i++)
{
if(sum+a[i]<m)
{
sum+=a[i];
ans=ans+a[i]*p[i];
//如果买这个还不够的话,全部买掉继续往下找
}
else
{
ans=ans+(m-sum)*p[i];
cout<<ans<<endl;
return 0;
//如果够了,只买自己需要的
//再完美的结束程序
}
}
}