BZOJ 1672: [Usaco2005 Dec]Cleaning Shifts 清理牛棚

题目

1672: [Usaco2005 Dec]Cleaning Shifts 清理牛棚

Time Limit: 5 Sec  Memory Limit: 64 MB

Description

Farmer John‘s cows, pampered since birth, have reached new heights of fastidiousness. They now require their barn to be immaculate. Farmer John, the most obliging of farmers, has no choice but hire some of the cows to clean the barn. Farmer John has N (1 <= N <= 10,000) cows who are willing to do some cleaning. Because dust falls continuously, the cows require that the farm be continuously cleaned during the workday, which runs from second number M to second number E during the day (0 <= M <= E <= 86,399). Note that the total number of seconds during which cleaning is to take place is E-M+1. During any given second M..E, at least one cow must be cleaning. Each cow has submitted a job application indicating her willingness to work during a certain interval T1..T2 (where M <= T1 <= T2 <= E) for a certain salary of S (where 0 <= S <= 500,000). Note that a cow who indicated the interval 10..20 would work for 11 seconds, not 10. Farmer John must either accept or reject each individual application; he may NOT ask a cow to work only a fraction of the time it indicated and receive a corresponding fraction of the salary. Find a schedule in which every second of the workday is covered by at least one cow and which minimizes the total salary that goes to the cows.

约翰的奶牛们从小娇生惯养,她们无法容忍牛棚里的任何脏东西.约翰发现,如果要使这群有洁癖的奶牛满意,他不得不雇佣她们中的一些来清扫牛棚, 约翰的奶牛中有N(1≤N≤10000)头愿意通过清扫牛棚来挣一些零花钱.由于在某个时段中奶牛们会在牛棚里随时随地地乱扔垃圾,自然地,她们要求在这段时间里,无论什么时候至少要有一头奶牛正在打扫.需要打扫的时段从某一天的第M秒开始,到第E秒结束f0≤M≤E≤86399).注意这里的秒是指时间段而不是时间点,也就是说,每天需要打扫的总时间是E-M+I秒. 约翰已经从每头牛那里得到了她们愿意接受的工作计划:对于某一头牛,她每天都愿意在笫Ti,.T2秒的时间段内工作(M≤Ti≤马≤E),所要求的报酬是S美元(0≤S≤500000).与需打扫时段的描述一样,如果一头奶牛愿意工作的时段是每天的第10_20秒,那她总共工作的时间是11秒,而不是10秒.约翰一旦决定雇佣某一头奶牛,就必须付给她全额的工资,而不能只让她工作一段时间,然后再按这段时间在她愿意工作的总时间中所占的百分比来决定她的工资.现在请你帮约翰决定该雇佣哪些奶牛以保持牛棚的清洁,当然,在能让奶牛们满意的前提下,约翰希望使总花费尽量小.

Input

* Line 1: Three space-separated integers: N, M, and E. * Lines 2..N+1: Line i+1 describes cow i‘s schedule with three space-separated integers: T1, T2, and S.

第1行:3个正整数N,M,E,用空格隔开.

第2到N+1行:第i+l行给出了编号为i的奶牛的工作计划,即3个用空格隔开的正整数Ti,T2,S.

Output

* Line 1: a single integer that is either the minimum total salary to get the barn cleaned or else -1 if it is impossible to clean the barn.

输出一个整数,表示约翰需要为牛棚清理工作支付的最少费用.如果清理工作不可能完成,

那么输出-1.

Sample Input

3 0 4 //三头牛,要打扫从0到4号stall
0 2 3 //一号牛,从0号stall打扫到2号,工资为3
3 4 2
0 0 1

INPUT DETAILS:

FJ has three cows, and the barn needs to be cleaned from second 0 to second
4. The first cow is willing to work during seconds 0, 1, and 2 for a total
salary of 3, etc.

Sample Output

5

HINT

约翰有3头牛,牛棚在第0秒到第4秒之间需要打扫.第1头牛想要在第0,1,2秒内工作,为此她要求的报酬是3美元.其余的依此类推.    约翰雇佣前两头牛清扫牛棚,可以只花5美元就完成一整天的清扫.

题解

这题就是一个常规DP,对于每个cow[i],查询区间cow[i].left-1~cow[i].right最小值再加上cow[i]的工资去更新cow[i].left~cow[i].right的答案,这样我们就需要一颗线段树了。我觉得应该是区间修改区间查询的啊,为什么他们直接单点查cow[i].left-1这个点的值去更新也能AC,不科学啊、、之前煞笔的几次Wa没看到还可以有不成立的情况QAQ【果然是因为觉得太简单所以就没把题目看完吗= =

代码

  1 /*Author:WNJXYK*/
  2 #include<cstdio>
  3 #include<algorithm>
  4 using namespace std;
  5
  6 int n,st,ed;
  7 struct line{
  8     int left,right;
  9     int w;
 10 }cow[10005];
 11 bool cmp(line a,line b){
 12     if (a.left<b.left) return true;
 13     return false;
 14 }
 15 inline int remin(int a,int b){
 16     if (a<b) return a;
 17     return b;
 18 }
 19 inline int remax(int a,int b){
 20     if (a>b) return a;
 21     return b;
 22 }
 23
 24 const int Maxn=86400;
 25 const int Inf=2000000000;
 26 struct Btree{
 27     int left,right;
 28     int min;
 29     int tag;
 30 }tree[Maxn*4+10];
 31
 32 void build(int x,int left,int right){
 33     tree[x].left=left;
 34     tree[x].right=right;
 35     tree[x].tag=Inf;
 36     if (left==right){
 37         tree[x].min=(left<st?0:Inf);
 38     }else{
 39         int mid=(left+right)/2;
 40         build(x*2,left,mid);
 41         build(x*2+1,mid+1,right);
 42         tree[x].min=remin(tree[x*2].min,tree[x*2+1].min);
 43     }
 44 }
 45
 46 inline void clean(int x){
 47     if (tree[x].left!=tree[x].right){
 48         tree[x*2].min=remin(tree[x].tag,tree[x*2].min);
 49         tree[x*2].tag=remin(tree[x].tag,tree[x*2].tag);
 50         tree[x*2+1].min=remin(tree[x].tag,tree[x*2+1].min);
 51         tree[x*2+1].tag=remin(tree[x].tag,tree[x*2+1].tag);
 52         tree[x].tag=Inf;
 53     }
 54 }
 55
 56 void change(int x,int left,int right,int val){
 57     clean(x);
 58     if (left<=tree[x].left && tree[x].right<=right){
 59         tree[x].tag=remin(tree[x].tag,val);
 60         tree[x].min=remin(tree[x].min,val);
 61     }else{
 62         int mid=(tree[x].left+tree[x].right)/2;
 63         if (left<=mid) change(x*2,left,right,val);
 64         if (right>=mid+1)change(x*2+1,left,right,val);
 65         tree[x].min=remin(tree[x*2].min,tree[x*2+1].min);
 66     }
 67 }
 68
 69 int query(int x,int left,int right){
 70     clean(x);
 71     if (left<=tree[x].left && tree[x].right<=right){
 72         return tree[x].min;
 73     }else{
 74         int Ans=Inf;
 75         int mid=(tree[x].left+tree[x].right)/2;
 76         if (left<=mid) Ans=remin(Ans,query(x*2,left,right));
 77         if (right>=mid+1) Ans=remin(Ans,query(x*2+1,left,right));
 78         return Ans;
 79     }
 80 }
 81
 82
 83 int main(){
 84     scanf("%d%d%d",&n,&st,&ed);
 85     int delta=0;
 86     if (st<1)delta=1-st;
 87     st+=delta;
 88     ed+=delta;
 89     build(1,0,ed);
 90     for (int i=1;i<=n;i++){
 91         scanf("%d%d%d",&cow[i].left,&cow[i].right,&cow[i].w);
 92         cow[i].left+=delta;
 93         cow[i].right+=delta;
 94     }
 95     sort(cow+1,cow+n+1,cmp);
 96     for (int i=1;i<=n;i++){
 97         int mindist=query(1,remax(cow[i].left-1,0),cow[i].right)+cow[i].w;
 98         //printf("mindist:%d\n",mindist);
 99         //printf("query %d %d -> min=%d\n",remax(cow[i].left-1,0),cow[i].right,query(1,cow[i].left,cow[i].right));
100         change(1,cow[i].left,cow[i].right,mindist);
101     }
102         //printf("query min=%d\n",query(1,ed,ed));
103     int ans=query(1,ed,ed);
104     if (ans==Inf)
105         printf("-1\n");
106     else
107         printf("%d\n",ans);
108     return 0;
109 }

时间: 2024-10-13 23:34:13

BZOJ 1672: [Usaco2005 Dec]Cleaning Shifts 清理牛棚的相关文章

[BZOJ1672][Usaco2005 Dec]Cleaning Shifts 清理牛棚

1672: [Usaco2005 Dec]Cleaning Shifts 清理牛棚 Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 953  Solved: 407 [Submit][Status][Discuss] Description Farmer John's cows, pampered since birth, have reached new heights of fastidiousness. They now require the

BZOJ 1672 Usaco 2005 Dec Cleaning Shifts 清理牛棚 动态规划

题目大意:有一些牛,他们的牛舍需要被打扫.有N(N <= 10000)头牛愿意打扫,从时间S到时间T,需要花费一些金钱.问若要每时每刻都有牛在打扫,至少需要花多少钱. 思路:1w的数据量不算很大,再加上时限5s,就n^2动归来做. 将牛按时间段的开始排序. 设f[i]为若取第i头牛打扫,到这头牛结束的时间最小花费是多少. 则    f[i] = min(f[i],f[j] + cost[i])  (f[i].st <= f[j].ed + 1) 最后是初值和答案的问题.由于题目中说每时每刻都有

[Usaco2005 Dec]Cleaning Shifts

[Usaco2005 Dec]Cleaning Shifts 给出n段区间,左右端点分别为\(l_i,r_i\),以及选取这段区间的费用\(c_i\),现在要选出若干个区间,使其完全覆盖区间\([m,e]\),询问费用之和的最小值,\(1≤n≤10000,0≤m≤e≤86399\). 解 法一: 不妨把区间按左端点排序,如果在大区间范围外,可以筛除,虽然题目有保障,于是设\(f_i\)表示以第i个区间结尾,覆盖第i个区间前所有需要覆盖的位置的最少代价,于是有 \[f_i=\min_{j=1,r_

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

题目 3389: [Usaco2004 Dec]Cleaning Shifts安排值班 Time Limit: 1 Sec  Memory Limit: 128 MB Description 一天有T(1≤T≤10^6)个时段.约翰正打算安排他的N(1≤N≤25000)只奶牛来值班,打扫 打扫牛棚卫生.每只奶牛都有自己的空闲时间段[Si,Ei](1≤Si≤Ei≤T),只能把空闲的奶牛安排出来值班.而且,每个时间段必需有奶牛在值班.  那么,最少需要动用多少奶牛参与值班呢?如果没有办法安排出合理的

Bzoj 3389: [Usaco2004 Dec]Cleaning Shifts安排值班 最短路,神题

3389: [Usaco2004 Dec]Cleaning Shifts安排值班 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 218  Solved: 86[Submit][Status][Discuss] Description 一天有T(1≤T≤10^6)个时段.约翰正打算安排他的N(1≤N≤25000)只奶牛来值班,打扫 打扫牛棚卫生.每只奶牛都有自己的空闲时间段[Si,Ei](1≤Si≤Ei≤T),只能把空闲的奶牛安排出来值班.而且,每个

bzoj 3389: [Usaco2004 Dec]Cleaning Shifts安排值班 -- 贪心

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

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

3389: [Usaco2004 Dec]Cleaning Shifts安排值班 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 102  Solved: 46[Submit][Status][Discuss] Description 一天有T(1≤T≤10^6)个时段.约翰正打算安排他的N(1≤N≤25000)只奶牛来值班,打扫 打扫牛棚卫生.每只奶牛都有自己的空闲时间段[Si,Ei](1≤Si≤Ei≤T),只能把空闲的奶牛安排出来值班.而且,每个

[USACO 05 DEC]Cleaning Shifts

题面描述 约翰的奶牛们从小娇生惯养,她们无法容忍牛棚里的任何脏东西.约翰发现,如果要使这群有洁癖的奶牛满意,他不得不雇佣她们中的一些来清扫牛棚,约翰的奶牛中有\(N(1 \leq N \leq 10000)\)头愿意通过清扫牛棚来挣一些零花钱. 由于在某个时段中奶牛们会在牛棚里随时随地地乱扔垃圾,自然地,她们要求在这段时间里,无论什么时候至少要有一头奶牛正在打扫.需要打扫的时段从某一天的第\(M\)秒开始,到第\(E\)秒结束\((0 \leq M \leq E \leq 86399)\).注意

BZOJ 1729: [Usaco2005 dec]Cow Patterns 牛的模式匹配

Description 约翰的N(1≤N≤100000)只奶牛中出现了K(1≤K≤25000)只爱惹麻烦的坏蛋.奶牛们按一定的顺序排队的时候,这些坏蛋总会站在一起.为了找出这些坏蛋,约翰让他的奶牛排好队进入牛棚,同时需要你的慧眼来识别坏蛋,为了区分,约翰给所有奶牛都发了号牌,上面写着一个1..S(1≤S≤25)之间的数字.虽然这不是一个完美的方法,但也能起一点作用.现在,约翰已经不记得坏蛋们的具体号码.但是凭他的记忆,他给出一个"模式串".原坏蛋的号码如果相同,模式串中他们的号码依然相