题意
1 主人公从0开始开始跑
2 使用速度非递减技能
3 警察记录下了多个整数时间点他的位置 整数时间点不明确
让我们求主人公所花费的最小时间跨越过最后一个位置点
分析
本体选用逆推处理
为啥用逆推 因为速度是非递减的 如果从前面推 会导致不断重复修改 前面的时间 时间不好把握最小
所以从后往前看每一段的速度就是递减的
为了保证最小 所以不如让最后一段的时间是个1 这里贪心一下 当求出最后一段的速度后 前面的每一段的速度都只能相同 或更慢 决不能更快
由于题目说明每个时间点是整数 所以每个时间点按照后面一段的速度求出来的时间一定是最快的
因为只能小于等于后面的速度 所以按照后面的速度求出来的时间必定是最快的 由于是整数所以
要向上取整 向下取整可能会比后面的速度快 不符题意 只能向上取整
开始速度用double做 一直WA 后来改用分数做后就A了- -
还是精度的地方惹不起 double的地方惹不起 还有ceil等返回值为double的地方惹不起
CODE
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
typedef long long ll;
const int maxn = 1e5+5;
ll a[maxn];
int main()
{int t;scanf("%d",&t);for(int j=1;j<=t;j++){int n;scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%lld",&a[i]);ll sum=0,lastt=0;int lvm=0,lvz=0;for(int i=n-1;i>=0;i--){ll p = a[i+1]-a[i];if(i==n-1)lastt=1,sum++;else{ll t = (ll)ceil(p*lastt/(double)lvz);//如果本段的距离小于上一段的 那么本段的速度不能比上一段的高 只能>=lastv 就直接带入上一段的速度取ceil 表示慢一点由于是整数所以就只能是慢一点sum+=t; //如果本段距离大于上一段的 那么就用上一段的速度 求出t来向上取整lastt=t;}lvm = lastt,lvz = p;}printf("Case #%d: %lld\n",j,sum);}return 0;
}