码迷,mamicode.com
首页 > 其他好文 > 详细

(水)POJ-3262 贪心,背包,比率问题

时间:2016-05-13 00:31:09      阅读:198      评论:0      收藏:0      [点我收藏+]

标签:

题目大意:

有n个牛在FJ的花园乱吃。

所以FJ要赶他们回牛棚。

每个牛在被赶走之前每秒吃Di个花朵。赶它回去FJ要花的时间是Ti,走回来再赶其他牛也需要Ti的时间。在被赶走的过程中牛就不能乱吃了


题目链接:点击打开链接


分析:这个题与贪心中的背包问题很像,都涉及到比率问题,按照比率来排序。背包问题中以 价值/质量 来从大到小排序,而这里我们以 D/T 来从大到小排序,以此顺序来赶牛就行了。

下面给出证明:

设di,ti,Ti分别代表编号为i(以 di / ti 从大到小依次编号)的牛每秒吃di个花朵,赶它花的时间是ti,经过Ti时间才被赶走,我们先来考虑牛1

对牛1有 d1 / t1 > dk / tk(1<k<=n),即 d1 * tk > dk * t1

按照上面的贪心思想,则牛1肯定最先被赶走。则此时的总花费为:

d1*T1+d2*T2.......+dn*Tn = d2*T2.......+dn*Tn    因为T1=0

若不先赶牛1,那么我们交换牛1与牛i的顺序。则此时的总花费发生了变化

1.对于牛i后面的牛,其T不变

2.对于牛1,T1‘ = T1+t2+t3.....+ti = t2+t3.....+ti

3.对于牛i ,Ti‘ = 0

4.对于编号在1到i之间的牛,Tk‘ = Tk+ ( ti - t1 )

所以此时的总花费为:

d1*T1‘+d2*T2‘...+dn*Tn‘ = (d2*T2.......+dn*Tn) + (d1*t2+d1*t3...+d1*ti) + (d2*ti+d3*ti...+di-1*ti) - (d2*t1+d3*t1...+di-1*t1) 

由于 d1 * tk > dk * t1,所以 (d1*t2+d1*t3...+d1*ti-1)-(d2*t1+d3*t1...+di-1*t1)>0

所以花费2 > 花费1

以此归纳,可知这种贪心方法是正确的。


附上代码:

#include<iostream>
#include<algorithm>
using namespace std;
struct Cow{ int t, d; Cow(int a = 0, int b = 0){ t = a, d = b; } }cow[100000 + 5];
long long ans, sum;
int n;
bool cmp(Cow &a, Cow &b){ return a.d * b.t > b.d * a.t; }  //为了避免除法产生小数而引起精度误差,我们采用相乘的形式
int main()
{
	scanf("%d", &n);
	for (int i = 1; i <= n; i++)
		scanf("%d%d", &cow[i].t, &cow[i].d);
	sort(cow + 1, cow + n + 1, cmp);
	for (int i = 1; i <= n; i++)
	{
		sum += cow[i - 1].t * 2;        //来回一共2倍t
		ans += sum * cow[i].d;
	}
	printf("%lld\n", ans);
	return 0;
}

(水)POJ-3262 贪心,背包,比率问题

标签:

原文地址:http://blog.csdn.net/ac_hell/article/details/51347842

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!