5775. 准时抵达会议现场的最小跳过休息次数(dp)

传送门

视频传送门

给你一个整数 hoursBefore ,表示你要前往会议所剩下的可用小时数。要想成功抵达会议现场,你必须途经 n 条道路。道路的长度用一个长度为 n 的整数数组 dist 表示,其中 dist[i] 表示第 i 条道路的长度(单位:千米)。另给你一个整数 speed ,表示你在道路上前进的速度(单位:千米每小时)。

当你通过第 i 条路之后,就必须休息并等待,直到 下一个整数小时 才能开始继续通过下一条道路。注意:你不需要在通过最后一条道路后休息,因为那时你已经抵达会议现场。

例如,如果你通过一条道路用去 1.4 小时,那你必须停下来等待,到 2 小时才可以继续通过下一条道路。如果通过一条道路恰好用去 2 小时,就无需等待,可以直接继续。
然而,为了能准时到达,你可以选择 跳过 一些路的休息时间,这意味着你不必等待下一个整数小时。注意,这意味着与不跳过任何休息时间相比,你可能在不同时刻到达接下来的道路。

例如,假设通过第 1 条道路用去 1.4 小时,且通过第 2 条道路用去 0.6 小时。跳过第 1 条道路的休息时间意味着你将会在恰好 2 小时完成通过第 2 条道路,且你能够立即开始通过第 3 条道路。
返回准时抵达会议现场所需要的 最小跳过次数 ,如果 无法准时参会 ,返回 -1 。

 

示例 1:

输入:dist = [1,3,2], speed = 4, hoursBefore = 2
输出:1
解释:
不跳过任何休息时间,你将用 (1/4 + 3/4) + (3/4 + 1/4) + (2/4) = 2.5 小时才能抵达会议现场。
可以跳过第 1 次休息时间,共用 ((1/4 + 0) + (3/4 + 0)) + (2/4) = 1.5 小时抵达会议现场。
注意,第 2 次休息时间缩短为 0 ,由于跳过第 1 次休息时间,你是在整数小时处完成通过第 2 条道路。
示例 2:

输入:dist = [7,3,5,5], speed = 2, hoursBefore = 10
输出:2
解释:
不跳过任何休息时间,你将用 (7/2 + 1/2) + (3/2 + 1/2) + (5/2 + 1/2) + (5/2) = 11.5 小时才能抵达会议现场。
可以跳过第 1 次和第 3 次休息时间,共用 ((7/2 + 0) + (3/2 + 0)) + ((5/2 + 0) + (5/2)) = 10 小时抵达会议现场。
示例 3:

输入:dist = [7,3,5,5], speed = 1, hoursBefore = 10
输出:-1
解释:即使跳过所有的休息时间,也无法准时参加会议。
 

提示:

n == dist.length
1 <= n <= 1000
1 <= dist[i] <= 105
1 <= speed <= 106
1 <= hoursBefore <= 107

这个题的题意就是说给你一个speed和每一段铁轨的长度,那么通过这一段铁轨的时间就是speed/dis[i],当然这个可能不是一个整数,如果不是一个整数的话。

那么你要休息一下等到整数再走,加入你通过这个铁轨的时间为1.2,那么你要休息到2.0,还有就是你可以施法一次,就是经过这个铁轨它不休息,就是还是1.2

直接到下一个铁轨,问你最少需要施法几次能在m时间内走完n个铁轨

这个题是一个n^2的dp

dp[i][j]代表的前i段铁轨施法j次最小的花费,然后这个题是可以n^2解决的

这个题解写的很清楚,可以看一下

传送门

 

然后这个还有一个精度的问题

 

 

const int maxn=1010;
const double esp=1e-8,INF=1e9;
double f[maxn][maxn];
class Solution {
public:
    int minSkips(vector<int>& dist, int speed, int m) {
        int n=dist.size();
        for(int i=1;i<=n;i++){
            double t=(double)dist[i-1]/speed;
            for(int j=0;j<=i;j++){
                f[i][j]=INF;
                if(j<=i-1){
                    f[i][j]=ceil(f[i-1][j]+t-esp);
                }
                if(j){
                    f[i][j]=min(f[i][j],f[i-1][j-1]+t);
                }
            }
        }
        for(int i=0;i<=n;i++){
            if(f[n][i]<=m){
                return i;
            }
        }
        return -1;
    }
};

 

posted @ 2021-05-30 21:44  lipu123  阅读(102)  评论(0编辑  收藏  举报