hihocoder 1583:Cake

hihocoder 1583:Cake

描述
To celebrate that WF-2018 will be held in PKU, Alice, Bob, and Cate are asked to make

N cakes.

Every cake i needs to go through 3 steps in restrict order:

  1. Alice mixes flour and water for ai minutes;

  2. Bob carefully bakes it for bi minutes;

  3. Cate makes cream decoration for ci minutes.

Since Cate wants to have different kinds of cakes, the third step of any cake i is always not less time-consuming than the second step of any cake j. Also, it is reasonable that once anyone starts to process a cake, the procedure cannot be stopped then be resumed.

To have these cakes done as soon as possible, they need your help.

输入
There are several cases (less than 15 cases).

The first line of every case contains an integer N (1 ≤ N ≤ 105)—the number of cakes to prepare.

After that, N lines follow, each of them contains three integers ai, bi and ci (1 ≤ i ≤ N; 0 <ai, bi, ci < 106)—time that needs to be spent on the three steps of cake i respectively.

It is guaranteed that for any i and any j, bi is no greater than cj.

The input ends with N = 0.

输出
For every case, print in a single line the least possible time to make all cakes.
样例提示
One of the optimal solutions is to have Alice and Bob process cakes in order of 2, 3, 1, while Cate processes cakes in order of 2, 1, 3.
在这里插入图片描述
样例输入
3
5 3 4
3 2 9
3 4 8
0
样例输出
26

题解
待求解问题其实就是一个时间分配问题,比较难思考,因为做一个蛋糕需要三个有顺序的步骤,做完第一个步骤才能做第二个步骤,并且除了第三个步骤时间必须大于第二个步骤,题目是没有给出其他时间大小前提的。一开始采用短时间优先以及动态规划的策略,首先对n个蛋糕的三个步骤分别从小到大排序,得到结构体n[i],并按此顺序执行。利用三个数组a[i],b[i],c[i]分别记录蛋糕i每一步骤完成时候的最短时间,除了蛋糕i第一步骤所需最短时间a[i]是按输入直接确定,之后的每一个步骤都需要和上一个蛋糕的相应步骤以及相应蛋糕的上一个步骤进行时间比较,因为必须要完成上一个步骤才能执行该步骤,所以可能两个蛋糕的同一步骤之间会存在休息时间,比如第二步骤b[i] =n[i].b+max(b[i-1],a[i]),最后得出来的最后一个蛋糕最后一个步骤所需最短时间出c[n-1]即为所求,以3 3 5 2 3 4 4 8 9为例分析,能清楚算出所需最短时间为26,
在这里插入图片描述

但是从整体来讲,我想到了一种改良后的思想,即其实只需要判断所有蛋糕i第一个步骤a[i]之和sum1以及第三个步骤c[i]之和sum2,因为根据只有前一个步骤完成才能执行当前步骤原理,无论哪种输入,假设sum1比sum2大,则最终时间应该是第一个做的蛋糕的前两个步骤时间之和加上sum1,反之则是最后一个做的蛋糕的后两个步骤时间之和加上sum2,因此为求最短时间,需要求出所有蛋糕中第一个步骤以及第二个步骤所需最短时间minab以及所有蛋糕中第二个步骤以及第三个步骤所需最短时间minbc,再根据sum1和sum2的大小比较,得出最终所需最短时间max(sum1+minbc,sum2+minab)。

#include<bits/stdc++.h>
using namespace std;
typedef int Int;
#define int long long
#define INF 0x3f3f3f3f
#define maxn 100005
int a[maxn],b[maxn],c[maxn];
Int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n;
    while(cin>>n&&n)
    { 
        int Minab=INF,Minbc=INF,sum1=0,sum2=0;
        for(int i=1;i<=n;i++)
        {
            cin>>a[i]>>b[i]>>c[i];
            sum1+=a[i];
            sum2+=c[i];
            Minab=min(a[i]+b[i],Minab);
            Minbc=min(b[i]+c[i],Minbc);
        }
        if(sum1>sum2)
        {
            cout<<sum1+Minbc<<endl;
        }
        else cout<<sum2+Minab<<endl;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值