2021-10-14

题目描述
There are N schedules, the i-th schedule has start time si and end time ei (1 <= i <= N). There are some machines. Each two overlapping schedules cannot be performed in the same machine. For each machine the working time is defined as the difference between timeend and timestart , where time_{end} is time to turn off the machine and timestart is time to turn on the machine. We assume that the machine cannot be turned off between the timestart and the timeend.
Print the minimum number K of the machines for performing all schedules, and when only uses K machines, print the minimum sum of all working times.
输入
The first line contains an integer T (1 <= T <= 100), the number of test cases. Each case begins with a line containing one integer N (0 < N <= 100000). Each of the next N lines contains two integers si and ei (0<=si<ei<=1e9).

输出
For each test case, print the minimum possible number of machines and the minimum sum of all working times
样例输入
1
3
1 3
4 6
2 5
样例输出
2 8
大概阐述一下这个题,一个工厂需要进行流水作业,一旦有重叠作业就需要开一台新的机器,每台机器在所有工作结束之前不允许关掉
大体思路:将所有开始时间和结束时间进行标记,开始时间标记为flag=1,结束时间标记为flag=-1,然后根据从小到大的次序对时间进行排序(将开始时间结束时间储存在一个数组,用flag判别是开始还是结束时间),一旦有相同的时间就把结束时间排在开始时间之前,然后对储存时间的数组进行处理,储存时间的数组元素自带下标flag,如果flag是1,-1,1,-1这样说明每个作业都没有重叠只需要一台机器,但是flag一旦出现连续几个1在一起说明时间有所重叠,连续出现几个1就需要有几台机器。
用一个sum函数来对机器数进行处理(sumans机器数),同时记录开始时间结束时间int sum=0,ans=0; for(int i=0;i<m;i++) { sum+=s[i].flag; if(sum>ans) { ans=sum; l[ans]=s[i].st; } }
只有当机器数进行改变的时候才记录开始和结束时间,用一个数组来储存每台机器开始时间,一个来储存每台结束时间,最后对几台机器的使用时间相加就是总的机器使用时间

#include <iostream>
#include <algorithm>
using namespace std;
struct node
{
    int st;
    int flag;
}s[100010*2];
int cmp(node a,node b)
{
    if(a.st!=b.st) return a.st<b.st;
    else return a.flag<b.flag;
}
int main() 
{
    int n;
    scanf("%d",&n);
    while(n--)
    {
        int r[100010]={0},l[100010]={0};
        int m=0,t;
        scanf("%d",&t);
        for(int i=0;i<t;i++)
        {
            int st,ed;
            scanf("%d%d",&st,&ed);
            s[m].st=st;s[m++].flag=1;
            s[m].st=ed;s[m++].flag=-1;
        }
        sort(s,s+m,cmp);
        int sum=0,ans=0;
        for(int i=0;i<m;i++)
        {
            sum+=s[i].flag;
            if(sum>ans)
            {
                ans=sum;
                l[ans]=s[i].st;
            }
        }
        sum=0,ans=0;
        for(int i=m-1;i>=0;i--)
        {
            sum-=s[i].flag;
            if(sum>ans)
            {
                ans=sum;
                r[ans]=s[i].st;
            }
        }
        int ttime=0;
        for(int i=1;i<=ans;i++)
        ttime+=r[i]-l[i];
        cout<<ans<<" "<<ttime<<endl;
    }
}

注意任何定义的后面不赋值的数一定要赋初值,否则会报错,
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值