POJ 3171.Cleaning Shifts-区间覆盖最小花费-dp+线段树优化(单点更新、区间查询最值)
| Time Limit: 1000MS | Memory Limit: 65536K | |
| Total Submissions: 4721 | Accepted: 1593 |
Description
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.
Input
Lines 2..N+1: Line i+1 describes cow i's schedule with three space-separated integers: T1, T2, and S.
Output
Sample Input
3 0 4
0 2 3
3 4 2
0 0 1
Sample Output
5
Hint
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.
Farmer John can hire the first two cows.
Source
题意就是给你一些小区间,用小区间去覆盖大区间,求最小花费。
数据结构优化动态规划,这是一个区间最值问题。
将小区间按照右端点排序,然后遍历小区间,每次都找小区间左边到小区间右边的最小值,然后最小值更新,只单点更新右端点就可以(降维)。
一开始想的区间更新,按照贴纸,直接成段更新,后来发现思路是错的,因为区间更新会覆盖掉其他的值。所以要用单点更新。
线段树每个点表示到当前区间段的最优解,直接初始化为inf,然后M-1更新为0,就可以。
每次都是查找a[i].l-1到a[i].r的最小值(因为是片段,所以从a[i].l-1开始查找),然后更新a[i].r。直接线段树维护区间的最小值。
动态规划方程式就是dp[i]=min(query(a[i].l-1,a[i].r))+a[i].val;表示覆盖到a[i].r的最小花费。因为小区间不能间断,所以要这样查询更新。
因为直接遍历的,所以dp[i]这个方程式都可以省略,直接查值然后更新值到线段树里就可以了。
因为每次都是从a[i].l-1开始,而且题目数据最小可能为0,所以直接端点都+2,这样,最小的值查找的时候也是从1开始的。
写题的时候,不能乱秀,容易把自己秀死。。。
自己写的时候,特判了一下如果最左端点和最端点不能包含大区间,直接-1输出。结果忘了我是按照右端点排序的,右边是对的,左边的不一定是对的。。。
最后直接查询大区间右端点和小区间最右端点。判断一下值就可以了。
如果ans<inf说明都能覆盖到,如果有inf说明有的地方没被覆盖到。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<bitset>
#include<cassert>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<deque>
#include<iomanip>
#include<list>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii; const double PI=acos(-1.0);
const double eps=1e-;
const ll mod=1e9+;
const ll inf=1e18;
const int maxn=1e5+;
const int maxm=+;
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1 struct node{
int l,r;
ll val; friend bool operator<(node a,node b){
if(a.r==b.r) return a.l<b.l;
return a.r<b.r;
} }a[maxn]; ll tree[maxn<<]; void pushup(int rt)
{
tree[rt]=min(tree[rt<<],tree[rt<<|]);
} void build(int l,int r,int rt)
{
if(l==r){
tree[rt]=inf;
return ;
} int m=(l+r)>>;
build(lson);
build(rson);
pushup(rt);
} void update(int pos,ll c,int l,int r,int rt)
{
if(l==r){
tree[rt]=min(tree[rt],c);
return ;
} int m=(l+r)>>;
if(pos<=m) update(pos,c,lson);
if(pos> m) update(pos,c,rson);
pushup(rt);
} ll query(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R){
return tree[rt];
} int m=(l+r)>>;
ll ret=inf;
if(L<=m) ret=min(ret,query(L,R,lson));
if(R> m) ret=min(ret,query(L,R,rson));
return ret;
} int main()
{
int n,M,E;
cin>>n>>M>>E;
for(int i=;i<=n;i++){
cin>>a[i].l>>a[i].r>>a[i].val;
a[i].l+=,a[i].r+=;
}
M+=,E+=;
sort(a+,a++n);
build(,maxn,);
update(M-,,,maxn,);
for(int i=;i<=n;i++){
ll cnt=query(a[i].l-,a[i].r,,maxn,);
cnt+=a[i].val;
update(a[i].r,cnt,,maxn,);
}
ll ans=query(E,a[n].r,,maxn,);
if(ans<inf) cout<<ans<<endl;
else cout<<"-1"<<endl;
}
OK了。
POJ 3171.Cleaning Shifts-区间覆盖最小花费-dp+线段树优化(单点更新、区间查询最值)的更多相关文章
- poj 3171 Cleaning Shifts(区间的最小覆盖价值)
Cleaning Shifts Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 2743 Accepted: 955 De ...
- POJ 2376 Cleaning Shifts 区间覆盖问题
http://poj.org/problem?id=2376 题目大意: 给你一些区间的起点和终点,让你用最小的区间覆盖一个大的区间. 思路: 贪心,按区间的起点找满足条件的并且终点尽量大的. 一开始 ...
- POJ 2892 Tunnel Warfare || HDU 1540(树状数组+二分 || 线段树的单点更新+区间查询)
点我看题目 题意 :N个村子连成一条线,相邻的村子都有直接的地道进行相连,不相连的都由地道间接相连,三个命令,D x,表示x村庄被摧毁,R ,表示最后被摧毁的村庄已经重建了,Q x表示,与x直接或间 ...
- POJ 3171 Cleaning Shifts(DP+zkw线段树)
[题目链接] http://poj.org/problem?id=3171 [题目大意] 给出一些区间和他们的价值,求覆盖一整条线段的最小代价 [题解] 我们发现对区间右端点排序后有dp[r]=min ...
- POJ 3171 Cleaning Shifts
Description Farmer John's cows, pampered since birth, have reached new heights of fastidiousness. Th ...
- [USACO2005][POJ3171]Cleaning Shifts(DP+线段树优化)
题目:http://poj.org/problem?id=3171 题意:给你n个区间[a,b],每个区间都有一个费用c,要你用最小的费用覆盖区间[M,E] 分析:经典的区间覆盖问题,百度可以搜到这个 ...
- POJ - 2376 Cleaning Shifts 贪心(最小区间覆盖)
Cleaning Shifts Farmer John is assigning some of his N (1 <= N <= 25,000) cows to do some clea ...
- poj3171 Cleaning Shifts【线段树(单点修改区间查询)】【DP】
Cleaning Shifts Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 4422 Accepted: 1482 D ...
- HDU 1540 Tunnel Warfare 平衡树 / 线段树:单点更新,区间合并
Tunnel Warfare Time Limit: 4000/2000 MS (Java/Others) Memory Lim ...
随机推荐
- linux内核的配置
以2.6.35.7版本的内核为例 总结:.config决定了Make时的条件编译与连接..config文件由两次配置第一次make XX_defconfig 第二次menuconfig. 1.分析源码 ...
- ps命令查看进程指定项目信息、用户名过长显示UID
有次一个在使用ps命令时,发现部分用户显示的是用户名,有些用户显示的是UID,那是因为用户名长度超过8位的:也就是说ps命令用户名列默认只能显示8位(含8位)的用户名,超过8位就显示UID,如何让长度 ...
- Android LayoutInflater深度解析
1. 题外话 相信大家对LayoutInflate都不陌生,特别在ListView的Adapter的getView方法中基本都会出现,使用inflate方法去加载一个布局,用于ListView的每个I ...
- js对数组的常用操作
在js中对数组的操作是经常遇到的,我呢在这就列一下经常用到的方法 删除数组中的元素: 1.delete方法:delete删除的只是数组元素的值,所占的空间是并没有删除的 代码: var arr=[12 ...
- Merge Query
1. Oracle: "MERGE into MHGROUP.proj_access m using dual on " + "(PRJ_ID = '" + W ...
- jedis,spring-redis-data 整合使用,版本问题异常
jedis,spring-redis-data 整合使用,版本不匹配的时候经常会报一些异常,例如1: java.lang.NoClassDefFoundError: org/springframewo ...
- Spark的Shuffle过程介绍
Spark的Shuffle过程介绍 Shuffle Writer Spark丰富了任务类型,有些任务之间数据流转不需要通过Shuffle,但是有些任务之间还是需要通过Shuffle来传递数据,比如wi ...
- centos6.8使用脚本一键搭建apache+svn服务
服务器环境: 脚本如下: #!/bin/bash yum install wget -y mv /etc/yum.repos.d/*.repo /tmp wget -O /etc/yum.repos. ...
- gridveiw的使用
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.UI ...
- http状态响应码对照表
1xx - 信息提示 这些状态代码表示临时的响应.客户端在收到常规响应之前,应准备接收一个或多个 1xx 响应. ·0 - 本地响应成功. · 100 - Continue 初始的请求已 ...