USACO 2010 Mar Silver 3.Need For Speed 贪心

Description
Bessie is preparing her race car for the upcoming Grand Prix, but she wants to buy some extra parts to improve the car's performance. Her race car currently has mass M (1 <= M <= 1,000) and is able to push itself forward with a force of F (1 <= F <= 1,000,000). The Race Car Performance Store has N (1 <= N <= 10,000) parts conveniently numbered 1..N. Bessie can buy as many or as few parts as she wishes though the store stocks no more than one instance of each part.

Part P_i adds force F_i (1 <= F_i <= 1,000,000) and has mass M_i (1 <= M_i <= 1,000). Newton's Second Law decrees that F = MA, where F is force, M is mass, and A is acceleration. If Bessie wants to maximize the total acceleration of her race car (and minimize the mass otherwise), which extra parts should she choose?

Consider a race car with initial F=1500 and M=100. Four parts are available for enhancement:

  i  F_i  M_i
          1  250   25
          2  150    9
          3  120    5
          4  200    8

Adding just part 2, e.g., would result in an acceleration of (1500+150)/(100+9) = 1650/109 = 15.13761.

Below is a chart of showing the acceleration for all possible combinations of adding/not-adding the four parts (in column one, 1=part added, 0=part not added):

Parts   Aggregate   Aggregate        
1234        F           M       F/M
0000      1500         100    15.0000
0001      1700         108    15.7407
0010      1620         105    15.4286
0011      1820         113    16.1062
0100      1650         109    15.1376
0101      1850         117    15.8120
0110      1770         114    15.5263
0111      1970         122    16.1475 <-- highest F/M
1000      1750         125    14.0000
1001      1950         133    14.6617
1010      1870         130    14.3846
1011      2070         138    15.0000
1100      1900         134    14.1791
1101      2100         142    14.7887
1110      2020         139    14.5324
1111      2220         147    15.1020

Thus, the best additional part combination is parts 2, 3, and 4.

Input
* Line 1: Three space-separated integers: F, M, and N

* Lines 2..N+1: Line i+1 contains two space separated integers: F_i and M_i

Output
* Lines 1..P: The index values of P extra parts, one per line, that Bessie should add to her racecar. If she should not add any, output 'NONE' (without quotes). The output should be given in increasing order, so if the optimal set of parts is {2,4,6,7}, then the output should be in the order 2,4,6,7 and not, for example, 4,2,7,6. Solutions will be unique.

Sample Input
1500 100 4
250 25
150 9
120 5
200 8

Sample Output
2
3
4

题意:有n个零件每一个零件都有一个动力fi和质量mi,初始的动力为F,质量为M,问怎么选能使总动力/总质量最大。

一看数据范围就觉得是贪心嘛,认为是先选fi/mi最大的,写了一个交上去AC了,后来想了半天该怎么证明。

证明在最下面。

代码:

#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
int F,M,n,flag;
double ans;
struct parts
{
	int f,m,Id,u;
}p[10010];
bool cmp(parts a,parts b)
{
	return (double)a.f/a.m>(double)b.f/b.m;
}
bool cmp2(parts a,parts b)
{
	return a.Id<b.Id;
}
int main()
{
	scanf("%d%d%d",&F,&M,&n);
	int i,j;
	for(i=1;i<=n;i++)
	{
		scanf("%d%d",&p[i].f,&p[i].m);
		p[i].Id=i;
	}
	sort(p+1,p+n+1,cmp);
	for(i=1;i<=n;i++)
	{
		if((double)(F+p[i].f)/(M+p[i].m)>(double)F/M)
		{
			F+=p[i].f;
			M+=p[i].m;
			p[i].u=1;
			flag=1;
		}
	}
	if(!flag)
	{
		printf("NONE");
		return 0;
	}
	sort(p+1,p+n+1,cmp2);
	for(i=1;i<=n;i++)
	{
		if(p[i].u)
		printf("%d\n",i);
	}
	return 0;
}

不妨先证明这个定理:

对于4个正整数a,b,c,d,若a/b>c/d,则a/b>(a+c)/(b+d)>c/d

证明如下:

 设a/b=k*c/d,(k>1)
 所以a/b=(k*c)/d 

 根据等比定理得:a/b=(a+k*c)/(b+d)=(k*c)/d

 因为(a+k*c)/(b+d)>(a+c)/(b+d)

 所以a/b>(a+c)/(b+d)

 又因为(k*c)/d>c/d

 所以(a+c)/(b+d)>c/d

 命题得证。

由此可知,对于任意的Fi/Mi>F/M,选这个零件后的状态肯定比当前状态更优(这里的F/M是之前所有的Fi,Mi和初始的F,M之和,也就是当前的F、M,所以由Fi/Mi>F/M可得(Fi+F)/(Mi+M)>F/M,所以更优),但不能保证选了这个零件后的状态就是是全局最优。不过,我们还可以得到,如果存在一个Fj/Mj比当前的Fi/Mi更优,那么在选了Fi/Mi之后,选Fj/Mj依然能够优化此时的状态(即Fj/Mj>Fi/Mi,则Fj/Mj>(Fi+F)/(Mi+M),所以更优),那么先选Fj/Mj不就好啦!

总而言之就是从最大的开始选就好了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值