• BZOJ3389: [Usaco2004 Dec]Cleaning Shifts安排值班


    3389: [Usaco2004 Dec]Cleaning Shifts安排值班

    Time Limit: 1 Sec  Memory Limit: 128 MB
    Submit: 45  Solved: 26
    [Submit][Status]

    Description

        一天有T(1≤T≤10^6)个时段.约翰正打算安排他的N(1≤N≤25000)只奶牛来值班,打扫
    打扫牛棚卫生.每只奶牛都有自己的空闲时间段[Si,Ei](1≤Si≤Ei≤T),只能把空闲的奶牛安排出来值班.而且,每个时间段必需有奶牛在值班.  那么,最少需要动用多少奶牛参与值班呢?如果没有办法安排出合理的方案,就输出-1.

    Input

     
        第1行:N,T.
        第2到N+1行:Si,Ei.

    Output

     
        最少安排的奶牛数.

    Sample Input


    3 10
    1 7
    3 6
    6 10

    Sample Output


    2


    样例说明
    奶牛1和奶牛3参与值班即可.

    HINT

     

    Source

    题解:
    此题<清理牛棚  线段树而已
    代码:
     1  #include<cstdio>
     2 #include<cstdlib>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<algorithm>
     6 #include<iostream>
     7 #include<vector>
     8 #include<map>
     9 #include<set>
    10 #include<queue>
    11 #include<string>
    12 #define inf 1000000000
    13 #define maxn 1000000+10000
    14 #define maxm 500+100
    15 #define eps 1e-10
    16 #define ll long long
    17 #define pa pair<int,int>
    18 #define for0(i,n) for(int i=0;i<=(n);i++)
    19 #define for1(i,n) for(int i=1;i<=(n);i++)
    20 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
    21 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
    22 #define mod 1000000007
    23 using namespace std;
    24 inline int read()
    25 {
    26     int x=0,f=1;char ch=getchar();
    27     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    28     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
    29     return x*f;
    30 }
    31 struct rec{int l,r;}a[maxn];
    32 struct seg{int l,r,mi,tag;}t[4*maxn];
    33 int n,m;
    34 inline bool cmp(rec a,rec b)
    35 {
    36     return a.l<b.l||(a.l==b.l&&a.r<b.r);
    37 }
    38 inline void pushup(int k)
    39 {
    40     t[k].mi=min(t[k<<1].mi,t[k<<1|1].mi);
    41 }
    42 inline void update(int k,int z)
    43 {
    44     t[k].mi=min(t[k].mi,z);
    45     t[k].tag=min(t[k].tag,z);
    46 }
    47 inline void pushdown(int k)
    48 {
    49     if(t[k].tag==inf)return ;
    50     update(k<<1,t[k].tag);
    51     update(k<<1|1,t[k].tag);
    52     t[k].tag=inf;
    53 }
    54 inline void build(int k,int x,int y)
    55 {
    56     int l=t[k].l=x,r=t[k].r=y,mid=(l+r)>>1;t[k].tag=inf;
    57     if(l==r){t[k].mi=l==0?0:inf;return ;}
    58     build(k<<1,l,mid);build(k<<1|1,mid+1,r);
    59     pushup(k);
    60 }
    61 inline ll query(int k,int x)
    62 {
    63     int l=t[k].l,r=t[k].r,mid=(l+r)>>1;
    64     if(l==r)return t[k].mi;
    65     pushdown(k);
    66     if(x<=mid)return query(k<<1,x);else return query(k<<1|1,x);
    67 }
    68 inline void change(int k,int x,int y,int z)
    69 {
    70     int l=t[k].l,r=t[k].r,mid=(l+r)>>1;
    71     if(l==x&&r==y){update(k,z);return;}
    72     pushdown(k);
    73     if(y<=mid)change(k<<1,x,y,z);
    74     else if(x>mid)change(k<<1|1,x,y,z);
    75     else change(k<<1,x,mid,z),change(k<<1|1,mid+1,y,z);
    76     pushup(k);
    77 }
    78 int main()
    79 {
    80     freopen("input.txt","r",stdin);
    81     freopen("output.txt","w",stdout);
    82     n=read();m=read();
    83     for1(i,n)a[i].l=read(),a[i].r=read();
    84     sort(a+1,a+n+1,cmp);
    85     build(1,0,m);
    86     for1(i,n)
    87     {
    88         ll t=query(1,a[i].l-1);
    89         if(t!=inf)change(1,a[i].l,a[i].r,t+1);else break;
    90     }
    91     ll ans=query(1,m);
    92     printf("%lld
    ",ans==inf?-1:ans);
    93     return 0;
    94 }
    View Code

     差了题解发现居然还有贪心做法:

    iwtwiioi:

    显然左端点排序后,依次取。

    要考虑下一次取的方案:

    待选点为a[j].x<=a[now].y+1的所有点j,其中now是当前所选

    那么我们要在这些点内做决策

    贪心就是取y最大的待选点,即

    max(a[j].y)的j

    orzzzzzzzzzz

    代码:(copy)

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cmath>
     4 #include <string>
     5 #include <iostream>
     6 #include <algorithm>
     7 #include <queue>
     8 using namespace std;
     9 #define rep(i, n) for(int i=0; i<(n); ++i)
    10 #define for1(i,a,n) for(int i=(a);i<=(n);++i)
    11 #define for2(i,a,n) for(int i=(a);i<(n);++i)
    12 #define for3(i,a,n) for(int i=(a);i>=(n);--i)
    13 #define for4(i,a,n) for(int i=(a);i>(n);--i)
    14 #define CC(i,a) memset(i,a,sizeof(i))
    15 #define read(a) a=getint()
    16 #define print(a) printf("%d", a)
    17 #define dbg(x) cout << #x << " = " << x << endl
    18 #define printarr2(a, b, c) for1(i, 1, b) { for1(j, 1, c) cout << a[i][j]; cout << endl; }
    19 #define printarr1(a, b) for1(i, 1, b) cout << a[i]; cout << endl
    20 inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; }
    21 inline const int max(const int &a, const int &b) { return a>b?a:b; }
    22 inline const int min(const int &a, const int &b) { return a<b?a:b; }
    23  
    24 const int N=25005;
    25 int n, t, cnt;
    26 struct dat { int x, y; }a[N];
    27 bool cmp(const dat &a, const dat &b) { return a.x==b.x?a.y<b.y:a.x<b.x; }
    28  
    29 int main() {
    30     read(n); read(t);
    31     for1(i, 1, n) read(a[i].x), read(a[i].y);
    32     sort(a+1, a+1+n, cmp);
    33     a[n+1].x=100055050;
    34     for1(i, 1, n) if(a[i].x!=a[i+1].x) a[++cnt]=a[i];
    35     if(a[1].x>1) { puts("-1"); return 0; }
    36     int ans=1, now=1;
    37     for1(i, 1, cnt) {
    38         int fix=0, nx=now, pos=0, ed=a[now].y;
    39         while(nx<cnt && a[nx+1].x<=ed+1) {
    40             ++nx;
    41             if(a[nx].y>ed && fix<a[nx].y) {
    42                 fix=a[nx].y;
    43                 pos=nx;
    44             }
    45         }
    46         if(a[now].y==t) break;
    47         if(nx==now || fix==0) { puts("-1"); return 0; }
    48         now=pos;
    49         i=nx;
    50         ++ans;
    51     }
    52     if(a[now].y!=t) puts("-1");
    53     else print(ans);
    54     return 0;
    55 }
    View Code

     卧槽,这题居然还能用最短路解,是有多少做法233333

    代码:(copy)

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<queue>
     5 #include<algorithm>
     6 #define pa pair<int,int>
     7 #define inf 1000000000
     8 #define ll long long
     9 using namespace std;
    10 inline int read()
    11 {
    12     int x=0;char ch=getchar();
    13     while(ch<'0'||ch>'9')ch=getchar();
    14     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    15     return x;
    16 }
    17 int n,T,cnt;
    18 bool vis[1000005];
    19 int dis[1000005],last[1000005];
    20 struct data{int to,next,v;}e[2000005];
    21 void insert(int u,int v,int w)
    22 {
    23     e[++cnt].to=v;e[cnt].next=last[u];last[u]=cnt;e[cnt].v=w;
    24 }
    25 void dijkstra()
    26 {
    27     priority_queue<pa,vector<pa>,greater<pa> >q;
    28     for(int i=1;i<=T;i++)dis[i]=inf;
    29     dis[0]=0;q.push(make_pair(0,0));
    30     while(!q.empty())
    31     {
    32         int now=q.top().second;q.pop();
    33         if(vis[now])continue;vis[now]=1;
    34         for(int i=last[now];i;i=e[i].next)
    35             if(dis[now]+e[i].v<dis[e[i].to])
    36             {
    37                 dis[e[i].to]=dis[now]+e[i].v;
    38                 q.push(make_pair(dis[e[i].to],e[i].to));
    39             }
    40     }
    41 }
    42 int main()
    43 {
    44     n=read();T=read();
    45     for(int i=1;i<=T;i++)
    46         insert(i,i-1,0);
    47     for(int i=1;i<=n;i++)
    48     {
    49         int a=read(),b=read();
    50         insert(a-1,b,1);
    51     }
    52     dijkstra();
    53     if(dis[T]==inf)puts("-1");
    54     else printf("%d
    ",dis[T]);
    55     return 0;
    56 }
    View Code
  • 相关阅读:
    容器镜像服务联手 IDE 插件,实现一键部署、持续集成与交付
    阿里巴巴大规模神龙裸金属 Kubernetes 集群运维实践
    4 个概念,1 个动作,让应用管理变得更简单
    从零开始入门 | Kubernetes 中的服务发现与负载均衡
    最佳实践 | 数据库迁云解决方案选型 & 流程全解析
    Thumbnail 图片帮助
    验证码-WebVcode
    访问者(Visitor)模式
    享元(Flyweight)模式
    中介者(Mediator)模式
  • 原文地址:https://www.cnblogs.com/zyfzyf/p/4005508.html
Copyright © 2020-2023  润新知