CodeForces702D. Road to Post Office(二分or数学)

D. Road to Post Office
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Vasiliy has a car and he wants to get from home to the post office. The distance which he needs to pass equals to d kilometers.

Vasiliy's car is not new — it breaks after driven every k kilometers and Vasiliy needs t seconds to repair it. After repairing his car Vasiliy can drive again (but after k kilometers it will break again, and so on). In the beginning of the trip the car is just from repair station.

To drive one kilometer on car Vasiliy spends a seconds, to walk one kilometer on foot he needs b seconds (a < b).

Your task is to find minimal time after which Vasiliy will be able to reach the post office. Consider that in every moment of time Vasiliy can left his car and start to go on foot.

Input

The first line contains 5 positive integers d, k, a, b, t (1 ≤ d ≤ 1012; 1 ≤ k, a, b, t ≤ 106; a < b), where:

  • d — the distance from home to the post office;
  • k — the distance, which car is able to drive before breaking;
  • a — the time, which Vasiliy spends to drive 1 kilometer on his car;
  • b — the time, which Vasiliy spends to walk 1 kilometer on foot;
  • t — the time, which Vasiliy spends to repair his car.
Output

Print the minimal time after which Vasiliy will be able to reach the post office.

Examples
Input
5 2 1 4 10
Output
14
Input
5 2 1 4 5
Output
13
Note

In the first example Vasiliy needs to drive the first 2 kilometers on the car (in 2 seconds) and then to walk on foot 3 kilometers (in 12 seconds). So the answer equals to 14 seconds.

In the second example Vasiliy needs to drive the first 2 kilometers on the car (in 2 seconds), then repair his car (in 5 seconds) and drive 2 kilometers more on the car (in 2 seconds). After that he needs to walk on foot 1 kilometer (in 4 seconds). So the answer equals to 13 seconds.

题意:路程d千米,车每行驶k千米就需要修理,车每行驶1千米要a分钟,步行1千米要b分钟,修车t分钟,求行驶d千米的最短时间。

思路:我用的是二分车要行驶的路程的方法,每次将车行驶时间和步行时间加起来,二分出最短时间,但是这个方法要先处理几个特殊情况。

另一种是直接的思维方法,当k>=d时候直接开车,否则如果a*k+t<b*k,就一直开车,最后d%k的路程考虑步行或者开车(开车要再修一次),

再不然就是前d/k-1次修车和开车的时间不少于直接步行的时间,所以只开一次车就步行。

方法一:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
int main()
{
    ll d, k, a, b, t, res;
    scanf("%I64d %I64d %I64d %I64d %I64d", &d, &k, &a, &b, &t);
    res = b*d;
    if(k >= d) res = min(res, a*d);//不修车
    else{//至少修一次
        ll tmp = t*(d/k)+a*d;
        if(d%k==0) tmp = t*(d/k-1)+a*d;//能整除最后一次不用修
        res = min(res, tmp);

        tmp = t*(d/k-1)+a*(d/k)*k+b*(d-d/k*k);//最后一次不修,步行
        res = min(res, tmp);

        res = min(res, a*k+(d-k)*b);//只开一次车不修
    }

    ll l = 0, r = d, m, t1, t2, n;
    while(l<=r){
        m = (l+r)/2;
        n = m/k;
        if(m%k==0&&m!=0) n--;
        t1 = t*n+a*(m/k*k)+(m-(m/k*k))*a;
        t2 = (d-m)*b;
        if(t1+t2<=res){
            l = m+1, res = t1+t2;
        }
        else r = m-1;
    }
    res = min(res, t1+t2);
    printf("%I64d\n", res);
}
方法二:
#include <bits/stdc++.h>
using namespace std;
#define ll long long int
int main()
{
    ll d, k, a, b, t, tt, ans;
    scanf("%I64d %I64d %I64d %I64d %I64d", &d, &k, &a, &b, &t);
    if(d<=k) ans = d*a;
    else {
        tt = a*k+t;
        if(tt<b*k){
            ans = d/k*k*a+(d/k-1)*t+min(t+(d%k)*a, (d%k)*b);//最后一段路修或者步行
        }else ans = a*k+(d-k)*b;//不需要修车
    }
    printf("%I64d\n", ans);
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值