2017北京网络赛 F - 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.

Input

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.

Output

For every case, print in a single line the least possible time to make all cakes.

Sample Input

3
5 3 4
3 2 9
3 4 8
0

Sample Output

26

题意:有n块蛋糕要做,每块蛋糕有三个步骤,其中第二个步骤花费的时间要不大于第三个步骤,如果当中有人停下来了,那就要重新开始,问做完n块蛋糕需要花费的最少的时间

题目思路:(这是倪娘的题目思路,代码也是根据倪娘的代码改写的,写个题解表示自己真正懂了这道题)因为做一个蛋糕要分三个步骤,做完一个步骤后才可以进行第二个步骤,而且中间不能有停顿。这里用样例来分析。那么可以先对三个步骤分别进行排序,从小到大。那么第一个步骤里最短时间是一定要加上去的,因为第一步骤不完成不能进行第二步骤。b[i]=n[i].b+max(b[i-1],a[i]);这一步表明了将第二个步骤的第二小时间与第一步骤的第二小时间进行比较,看那个时间比较大,因为第二步骤的最短时间到第二步骤的第二短时间中间有休息时间,如果a[0]+b[0]+b[1]+休息时间(a[1]-b[0])>a[0]+a[1],那么b[1]就从b[0]中加。c[i]也以此类推,一定要与(b[i]+休息时间)恰好衔接,否则就向前推一个c[i-1],最后将恰好衔接的三部分时间相加并加上剩下的c[i]的时间就是最短时间。(该段文字配合下图食用)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<string>
#include<queue>
#include<vector>
#include<stack>
#include<list>
using namespace std;
#define PI 3.1415927
#define maxn 100100
typedef long long ll;
ll a[maxn],b[maxn],c[maxn];
struct Node{
	int a,b,c;
}n[maxn];
int cal(Node x,Node y){
	int A=x.a,B=A+x.b,C=B+x.c;
	A+=y.a;
	B=max(A,B)+y.b;
	C=max(B,C)+y.c;
	return C;
}
bool cmp(Node x,Node y)
{
	return cal(x,y)<cal(y,x);
}
int main()
{
	int m;
	while(cin>>m)
	{
		if(m==0)
    	break;
    	memset(a,0,sizeof(a));
    	memset(b,0,sizeof(b));
    	memset(c,0,sizeof(c));
    	for(int i=0;i<m;i++) 
		    cin>>n[i].a>>n[i].b>>n[i].c;
		sort(n,n+m,cmp);
		for(int i=0;i<m;i++)
		if(a[i]=!i)
		a[i]=n[i].a;
		else
		a[i]=a[i-1]+n[i].a;
		for(int i=0;i<m;i++)
		if(b[i]=!i)
		b[i]=n[i].b+a[i];
		else
		b[i]=n[i].b+max(b[i-1],a[i]);
		for(int i=0;i<m;i++)
		if(c[i]=!i)
		c[i]=n[i].c+b[i];
		else
		c[i]=n[i].c+max(c[i-1],b[i]);
		printf("%lld\n",c[m-1]);
	}
	return 0;
 } 

 

思路二:(顾大佬的思路)直接将c的所有时间相加,再从a和b里挑最短的时间相加

#include <iostream>
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <map>
#include <stack>
#include <set>
#include<cstdlib>
using namespace std;
typedef long long ll;
#define pi 3.14159265358979323846264338327
#define E 2.71828182846
#define INF 0x3f3f3f3f
#define maxn 1311000

ll a[maxn],b[maxn],c[maxn];

int main(){
    int T;
    while(scanf("%d",&T),T){
        ll sum1=0,sum3=0;
        ll minab=INF,minbc=INF;
        for(int i=1;i<=T;i++){
            scanf("%lld %lld %lld",&a[i],&b[i],&c[i]);
            sum1+=a[i];
            sum3+=c[i];
            if(minab>a[i]+b[i])minab=a[i]+b[i];
            if(minbc>b[i]+c[i])minbc=b[i]+c[i];
        }
        printf("%lld\n",max(sum1+minbc,sum3+minab));
    }
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值