hdu 6180 Schedule

Schedule

 

Problem Description
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.
 

 

Input
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).
 

 

Output
For each test case, print the minimum possible number of machines and the minimum sum of all working times.
 

 

最近真的是愈发感觉自己很菜了   很伤感啊....
好不容易感觉有道签到题目可以写  结果写了两个小时  
WA了6发 T了2发  菜的一匹~~~
 
题意:工厂加工零件  问最少能用几个机器 和 机器所用的最少的时间
 
大概是不知道套路吧...等明天看别人的帖子  再学学新的套路
 
就是贪心  但是我只想到了 选择 间距最短的 用一个机器 这样能保证所用的时间最少  
 
但,但是我就是不会写  就很GG
 
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct node
{
    int st;//记录入点和出点
    int flag;//如果是入点就+1,否则就-1
}s[100000*2+100];

int L[100000+100],R[100000+100];//记录机器的开始时间 和 结束时间

bool cmp(node a,node b)
{
    if(a.st != b.st)
        return a.st<b.st;//就是按照端点排序
    else
        return a.flag < b.flag;//因为区间结束的时候 和另一个区间开始的会重叠
        //so 让区间先结束 然后在开始 这样子的吧
}

void init()
{
    memset(L,0,sizeof(L));
    memset(R,0,sizeof(R));
}
int main ()
{
    int t;
    scanf("%d",&t);
    while (t--)
    {
        init();
        int n;
        scanf("%d",&n);
        int m=0;
        for(int i=0;i<n;i++)
        {
            int st,e;
            scanf("%d %d",&st,&e);
            s[m].st = st,s[m++].flag=1;//左端点+1
            s[m].st = e,s[m++].flag=-1;//右端点-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[sum] = 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[sum] = s[i].st;
            }
        }
        ll res=0;
        for(int i=1;i<=ans;i++)
        {
            res += (R[i]-L[i]);
        }//因为最后就是R-L  所以这里不用管 R[i]和L[i]是否对应
        cout<<ans<<" "<<res<<endl;
    }
}

 

 上面真的是 奇思妙想  
下面这个才是 真正模拟的吧   可惜 我贪心大概只会sort  会一丢丢priority_queue  没写过用set的题 果然见识太短
不好
 
#include<bits/stdc++.h>
using namespace std;
struct node{
    int l,r;
    bool operator <(const node a)const{
        return l<a.l;
    }
}seg[100000];
multiset<int>s;
multiset<int>::iterator it;
int main()
{
    int t;
    scanf("%d",&t);
    while (t--)
    {
        s.clear();
        int n;
        scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
            scanf("%d %d",&seg[i].l,&seg[i].r);
        }
        int ans = 0;//记录所用机器数量
        long long res = 0;//记录时间
        sort(seg,seg+n);
        for(int i=0;i<n;i++)
        {
            it = s.upper_bound(seg[i].l);//寻找 >= seg[i].l 的r
            if(it == s.begin())
            {
                ans++;   //找不到 就重新开一个机器
                res += seg[i].r - seg[i].l;
                s.insert(seg[i].r);
                continue;
            }
            it--;//这里就是离该i区间的起始点最近的 结束点
            res += seg[i].r - *it;//把该i区间的结束点 接上上个结束点 这样就不用管 起始点在哪里了
            s.erase(it);//把当前区间结束点删除
            s.insert(seg[i].r);//重新更新
        }
        cout<<ans<<" "<<res<<endl;
    }
}

 

 

转载于:https://www.cnblogs.com/Draymonder/p/7425415.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值