[Usaco2005 Dec] Cleaning Shifts 清理牛棚

题目描述

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秒.约翰一旦决定雇佣某一头奶牛,就必须付给她全额的工资,而不能只让她工作一段时间,然后再按这段时间在她愿意工作的总时间中所占的百分比来决定她的工资.现在请你帮约翰决定该雇佣哪些奶牛以保持牛棚的清洁,当然,在能让奶牛们满意的前提下,约翰希望使总花费尽量小.

输入输出格式

输入格式:

  • 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.

输出格式:

  • 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.

输入输出样例

输入样例#1:

3 0 4

0 2 3

3 4 2

0 0 1

输出样例#1:

5

说明

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

Solution

再简述一下题意:给定一个区间\([L,R]\),以及\(n\)头牛,每头牛有一个自己打扫的区间\([t1,t2]\),以及花费\(c_i\),不可以让一头牛只打扫一部分区间,然后只付给它一部分钱(也就是说,区间是固定的,花费也是固定的,无法拆开),现在我们要用最少的花费使得\([L,R]\)内都有牛在打扫,问这个最小花费是多少?

很容易想到为了消除\(dp\)的后效性,我们要把所有的奶牛按左端点或者按右端点排序(如果按左端点排序就是由当前枚举的去更新后面的,如果按右端点排序就是由之前枚举的来更新过当前枚举的)

博主在这里用的是按右端点排序

设计状态:\(dp[i]\)表示从L开始,到i为止每个点都有牛在打扫的最小花费

目标状态:\(dp[R]\)

思考状态转移方程:\(dp[t[i].r]=min(dp[j])+t[i].v(t[i].l-1<=j<=t[i].r)\)

为什么范围是这个?首先,我们要保证当前区间之前的点都已经被覆盖,所以最多只能到\(t[i].l-1\),而当前区间是可以更新\(t[i].r\)这个点的,所以右端点要到\(t[i].r\),然后取个最小值

然后暴力打居然有90分?exm????

#include<bits/stdc++.h>
#define rg register
#define il extern inline
#define Min(a,b) (a)<(b)?(a):(b)
#define Max(a,b) (a)>(b)?(a):(b) using namespace std; const int N=1e4+10,inf=2e9,L=0,R=86500; void in(int &ans)
{
ans=0; int f=1; char i=getchar();
while(i<'0' || i>'9') {if(i=='-') f=-1;i=getchar();}
while(i>='0' && i<='9') ans=(ans<<1)+(ans<<3)+i-'0',i=getchar();
ans*=f;
} int n,l,r,cnt;
int dp[N*10];
struct node {
int l,r,v;
bool operator < (const node &a) const {return r<a.r;}
}t[N]; int main()
{
in(n),in(l),in(r);
for(rg int i=1;i<=n;i++) {
int a,b,c; in(a),in(b),in(c);
if(a>r || b<l) continue;
if(a<l) a=l; if(b>r) b=r;
t[++cnt]=(node){a,b,c};
}
sort(t+1,t+1+cnt);
memset(dp,0x3f,sizeof(dp)); dp[l]=0;
for(rg int i=1;i<=cnt;i++) {
int k=inf;
for(rg int j=t[i].l-1;j<=t[i].r;j++) k=Min(k,dp[j]);
dp[t[i].r]=Min(dp[t[i].r],k+t[i].v);
}
if(dp[r]==dp[r+1]) dp[r]=-1;
cout<<dp[r]<<endl;
}

那么想一下怎么优化?找最小值?RMQ?ST表/线段树.带修改?果断线段树

范围比较小,不用离散,直接建树就可以了

Code

#include<bits/stdc++.h>
#define rg register
#define il extern inline
#define Min(a,b) (a)<(b)?(a):(b)
#define Max(a,b) (a)>(b)?(a):(b)
#define ll(i) (i<<1)
#define rr(i) (i<<1|1) using namespace std; const int N=1e4+10,inf=2e9,L=0,R=86500; void in(int &ans)
{
ans=0; int f=1; char i=getchar();
while(i<'0' || i>'9') {if(i=='-') f=-1;i=getchar();}
while(i>='0' && i<='9') ans=(ans<<1)+(ans<<3)+i-'0',i=getchar();
ans*=f;
} int n,l,r,cnt;
int dp[N*10],sum[N*40];
struct node {
int l,r,v;
bool operator < (const node &a) const {return r<a.r;}
}t[N]; il void up(int node) {sum[node]=Min(sum[ll(node)],sum[rr(node)]);} void update(int node,int l,int r,int pos) {
if(l>pos || r<pos) return;
if(l==pos && r==pos) {sum[node]=Min(sum[node],dp[pos]);return;}
int mid=l+r>>1;
update(ll(node),l,mid,pos);
update(rr(node),mid+1,r,pos);
up(node);
} int check(int node,int l,int r,int left,int right) {
if(l>right || r<left) return inf;
if(l>=left && r<=right) return sum[node];
int mid=l+r>>1;
int a=check(ll(node),l,mid,left,right);
int b=check(rr(node),mid+1,r,left,right);
return Min(a,b);
} int main()
{
in(n),in(l),in(r);
for(rg int i=1;i<=n;i++) {
int a,b,c; in(a),in(b),in(c);
if(a>r || b<l) continue;
if(a<l) a=l; if(b>r) b=r;
t[++cnt]=(node){a,b,c};
}
sort(t+1,t+1+cnt);
memset(dp,0x3f,sizeof(dp));
memset(sum,0x3f,sizeof(sum));
dp[l]=0; update(1,L,R,l);
for(rg int i=1;i<=cnt;i++) {
int k=check(1,L,R,t[i].l-1,t[i].r)+t[i].v;
if(dp[t[i].r]>k) {
dp[t[i].r]=k;
update(1,L,R,t[i].r);
}
}
if(dp[r]==dp[r+1]) dp[r]=-1;
cout<<dp[r]<<endl;
}

博主蒟蒻,随意转载.但必须附上原文链接

http://www.cnblogs.com/real-l/

[Usaco2005 Dec]Cleaning Shifts 清理牛棚 (DP优化/线段树)的更多相关文章

  1. BZOJ_1672_[Usaco2005 Dec]Cleaning Shifts 清理牛棚_动态规划+线段树

    BZOJ_1672_[Usaco2005 Dec]Cleaning Shifts 清理牛棚_动态规划+线段树 题意:  约翰的奶牛们从小娇生惯养,她们无法容忍牛棚里的任何脏东西.约翰发现,如果要使这群 ...

  2. 洛谷P4644 [USACO2005 Dec]Cleaning Shifts 清理牛棚 [DP,数据结构优化]

    题目传送门 清理牛棚 题目描述 Farmer John's cows, pampered since birth, have reached new heights of fastidiousness ...

  3. 【bzoj1672】[USACO2005 Dec]Cleaning Shifts 清理牛棚 dp/线段树

    题目描述 Farmer John's cows, pampered since birth, have reached new heights of fastidiousness. They now ...

  4. BZOJ1672: [Usaco2005 Dec]Cleaning Shifts 清理牛棚

    1672: [Usaco2005 Dec]Cleaning Shifts 清理牛棚 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 414  Solved: ...

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

    题目 1672: [Usaco2005 Dec]Cleaning Shifts 清理牛棚 Time Limit: 5 Sec  Memory Limit: 64 MB Description Farm ...

  6. P4644 [Usaco2005 Dec]Cleaning Shifts 清理牛棚

    P4644 [Usaco2005 Dec]Cleaning Shifts 清理牛棚 你有一段区间需要被覆盖(长度 <= 86,399) 现有 \(n \leq 10000\) 段小线段, 每段可 ...

  7. 【BZOJ1672】[Usaco2005 Dec]Cleaning Shifts 清理牛棚 动态规划

    [BZOJ1672][Usaco2005 Dec]Cleaning Shifts Description Farmer John's cows, pampered since birth, have ...

  8. 【BZOJ】1672: [Usaco2005 Dec]Cleaning Shifts 清理牛棚(dp/线段树)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1672 dp很好想,但是是n^2的..但是可以水过..(5s啊..) 按左端点排序后 f[i]表示取第 ...

  9. 【bzoj1672】[USACO2005 Dec]Cleaning Shifts 清理牛棚

    题目描述 Farmer John's cows, pampered since birth, have reached new heights of fastidiousness. They now ...

随机推荐

  1. mybatis动态列名

    mybatis动态列名 <select id="getUser" resultType="java.util.Map" parameterType=&qu ...

  2. (数据科学学习手札18)二次判别分析的原理简介&Python与R实现

    上一篇我们介绍了Fisher线性判别分析的原理及实现,而在判别分析中还有一个很重要的分支叫做二次判别,本文就对二次判别进行介绍: 二次判别属于距离判别法中的内容,以两总体距离判别法为例,对总体G1,, ...

  3. uber司机已经激活了,就是还没有上传头

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  4. P3527 [POI2011]MET-Meteors

    P3527 [POI2011]MET-Meteors 链接 整体二分! 代码 #include<bits/stdc++.h> using namespace std; typedef lo ...

  5. java线程池技术

    1.线程池的实现原理?简介: 多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力.假设一个服务器完成一项任务所需时间为:T1 创建线程时间, ...

  6. unity3d easytouch计算摇杆旋转角度以及摇杆八方向控制角色

    在写第三人称控制的时候,一开始在电脑测试是用WASD控制角色 后来需要发布到手机上,于是就加了一个摇杆 键盘控制角色的代码已经写好了,角色八方向移动 如果按照传统的大众思路来控制的话,是达不到我想要的 ...

  7. Python-类-函数参数-takes 0 positional arguments but 1 was given

    在学习Python基础的时候,在创建某一个shownametest()函数,解析器会报错 TypeError: shownametest() takes 0 positional arguments ...

  8. Java并发基础--线程通信

    java中实现线程通信的四种方式 1.synchronized同步 多个线程之间可以借助synchronized关键字来进行间接通信,本质上是通过共享对象进行通信.如下: public class S ...

  9. Mysql字符串截取:Left()、Right()、Substring()、Substring_index()

    在实际的项目开发中有时会有对数据库某字段截取部分的需求,这种场景有时直接通过数据库操作来实现比通过代码实现要更方便快捷些, mysql有很多字符串函数可以用来处理这些需求,如Mysql字符串截取总结: ...

  10. 关于react-redux中Provider、connect的解析

    Provider 是什么 react-redux 提供的一个 React 组件 作用 把 store 提供给其子组件 //使用 redux 的 createStore 方法创建的一个 store co ...