hihoCoder175

题目1 : Robots Crossing River

描述
Three kinds of robots want to move from Location A to Location B and then from Location B to Location C by boat.

The only one boat between A and B and only one between B and C. Moving from A to B (and vise versa) takes 2 hours with robots on the boat. Moving from B to C (and vice versa) takes 4 hours. Without robots on the boat the time can be reduced by half. The boat between A and B starts at time 0 moving from A to B. And the other boat starts 2 hours later moving from B to C.

You may assume that embarking and disembarking takes no time for robots.

There are some limits:

  1. Each boat can take 20 robots at most.

  2. On each boat if there are more than 15 robots, no single kind of robots can exceed 50% of the total amount of robots on that boat.

  3. At most 35 robots are allowed to be stranded at B. If a robot goes on his journey to C as soon as he arrives at B he is not considered stranded at B.

Given the number of three kinds robots what is the minimum hours to take them from A to C?

输入
Three integers X, Y and Z denoting the number of the three kinds of robots. (0 ≤ X, Y and Z ≤ 1000)

输出
The minimum hours.

样例输入
40 4 4
样例输出
24

题目分析,直接搬运大犇思路了

首先需要看出整个流程的瓶颈完全在B-C这一段,换句话说我们只需求出所有机器人从B到C的最少时间,再加上2小时就是答案。事实上这个时间恰好等于把所有机器人直接从B运到C最少需要的船次x6。

如果没有“一船超过15个机器人则每种机器人不能超过半数”的限制,我们只需要20/船运走即可,最少船次是ceil((X+Y+Z)/20)。

由于有上面的限制,我们需要仔细讨论一下XYZ的相对大小。不妨设X >= Y >= Z,同时我们称三种机器人也为X、Y、Z类。

1、如果X <= Y + Z,那么我们仍然可以20/船运走,同时所有船都没有机器人超过半数。

这种情况最少船次仍然是是ceil((X+Y+Z)/20)。

2、 如果X > Y + Z,这时我们没办法使所有船都载20机器人。但是我们当然希望能尽量派出载20机器人的船。于是有如下贪心策略:

1) 首先尽量10个X类和10个非X类组成一船,派出若干船直到非X类不足10个机器人。
2) 余下若干(不足10个)非X类机器人,配合尽可能多X类机器人组成一船。这里需要讨论余下的非X类机器人有多少个,不妨设为K。如果K不足8个,那么最多配合15-K个X类机器人,组成一船15个机器人;否则可以配合K个X类机器人,组成一船2K个机器人。
3) 最后只剩下若干X类机器人,这些机器人只能15/船派出。

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

using namespace std;

int main()
{

    int x,y,z,a,b,c;
    cin>>x>>y>>z;
    int sum = x+y+z;
    a = max(max(x,y),z);
    b = min(min(x,y),z);
    c = sum-a-b;
    int ans = 0;
    if(b+c >= a){
        ans = ceil(sum/20.0);
    }
    else{
        int res = b+c;
        while(res >= 10){
            a -=10;
            res -= 10;
            ans++;
        }
        if(res < 8){
            a = a - 15 + res;
            ans++;
        }
        else{
            a = a-res;
            ans++;
        }
        if(a>0) ans += ceil(a/15.0);
    }

    cout<<ans*6<<endl;


    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值