题目链接:https://vjudge.net/problem/POJ-3262
题意:有n头牛,第i头牛吃花的速度是di朵/分钟,将它赶回棚需要ti分钟(来回则需要2*ti),求将所有的牛赶回去后最少吃了多少朵花
给出一个结论:按照di/ti降序排列时选取牛的顺序是最优的,简要证明:
对于一个顺序...(a,b),(c,d)...,可以将其调换为...(c,d),(a,b)...。设之前用了x分钟,
对于第一种情况,损失1=x*b+x*d+2a*d,对于第二种,损失2=x*d+x*b+2b*c。若损失1<损失2,则推出b/a>d/c,同理若损失2<损失1,则d/c>b/a。所以对于序列中两个二元组,按照di/ti降序排列时最优,从而对于整个序列也最优。注意点:写比较函数时用乘法来写
1 #include<cstdio> 2 #include<algorithm> 3 #define ll long long 4 using namespace std; 5 6 const int maxn=1000+10; 7 struct node{ 8 ll t,d; 9 }a[maxn]; 10 int n,i,j,k; 11 12 bool cmp(node p,node q){return p.d*q.t>q.d*p.t;} 13 14 int main(){ 15 //freopen("poj3262.txt","r",stdin); 16 scanf("%d",&n); 17 for (i=1;i<=n;i++) { 18 scanf("%lld%lld",&a[i].t,&a[i].d); 19 a[i].t*=2; 20 } 21 ll s=0;ll ans=0; 22 sort(a+1,a+n+1,cmp); 23 for (i=2;i<=n;i++) s+=a[i].d; 24 for (i=2;i<=n;i++){ 25 ans+=a[i-1].t*s; 26 s-=a[i].d; 27 } 28 printf("%lld ",ans); 29 //fclose(stdin); 30 return 0; 31 }