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\n",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\n",dis[T]);
55     return 0;
56 }
View Code

 

posted @ 2014-10-04 00:05  ZYF-ZYF  Views(306)  Comments(0Edit  收藏  举报