hdu5935 Car 贪心 卡精度

Car

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 393    Accepted Submission(s): 143


Problem Description
Ruins is driving a car to participating in a programming contest. As on a very tight schedule, he will drive the car without any slow down, so the speed of the car is non-decrease real number.

Of course, his speeding caught the attention of the traffic police. Police record  N  positions of Ruins without time mark, the only thing they know is every position is recorded at an integer time point and Ruins started at  0 .

Now they want to know the  minimum time that Ruins used to pass the last position.
 

Input
First line contains an integer  T , which indicates the number of test cases.

Every test case begins with an integers  N , which is the number of the recorded positions.

The second line contains  N  numbers  a1 a2 aN , indicating the recorded positions.

Limits
1T100
1N105
0<ai109
ai<ai+1
 

Output
For every test case, you should output  'Case #x: y', where  x indicates the case number and counts from  1 and  y is the minimum time.
 

Sample Input
  
  
1 3 6 11 21
 

Sample Output
  
  
Case #1: 4
 


贪心策略,倒着看,从后往前,后面的速度尽可能的大,这样才能保证总的时间最短

那么就确定了最后一段的时间为1,这样最后一段的速度就最大化了,把这个速度往前面传,用前一段距离除以后一段速度,得到时间,如果得到的时间不是整数,要向上取整(因为要保证前面的速度比后面的速度小),然后再用这个时间算当前段的实际速度,继续把新的速度往前面传……

本来想用double表示速度,ceil向上取整,结果WA,可能是精度损失,换成分数就过了,真坑



#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>

using namespace std;

typedef long long ll;

int T, n, kase, ans, t;
int a[100005];

int main()
{
	cin >> T;
	kase = 0;
	while (T--) {
		scanf("%d", &n);
		for (int i = 1; i <= n; i++) {
			scanf("%d", &a[i]);
		}
		a[0] = 0;
		ll fenzi, fenmu;
		ans = 0;
		for (int i = n - 1; i >= 0; i--) {
			if (i == n - 1) {
				t = 1;
				fenzi = a[i + 1] - a[i];
				fenmu = 1;
				ans += t;
			}
			else {
				int dis = a[i + 1] - a[i];
				fenmu *= dis;
				swap(fenmu, fenzi);
				if (fenzi % fenmu) {
					t = fenzi / fenmu + 1;
				}
				else {
					t = fenzi / fenmu;
				}
				ans += t;
				fenzi = a[i + 1] - a[i];
				fenmu = t;
			}
		}
		printf("Case #%d: %d\n", ++kase, ans);
	}
	return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值