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下bash脚本语法
1.shell中的变量定义和引用(1)变量定义和初始化.shell是弱类型语言(语言中的变量如果有明确的类型则属于强类型语言:变量没有明确类型就是弱类型语言),和C语言不同.在shell编程中定义变量 ...
- CMDB资产管理系统开发【day26】:CMDB上节回顾
一.上节知识点回顾 服务器设计了一个表结构 开发了一个客户端 二.后台创建缓存区表 客户端连接服务器,在服务器的下面看报错信息 因为URL都没有写,所以我找不到呀 1.在MadKing\url.py ...
- 剑指offer --合并链表
题目:输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则. 解法://递归解法 public class MixLink { /* public class L ...
- UVALive-4670 Dominating Patterns / 洛谷 3796 【模板】AC自动机
https://vjudge.net/problem/UVALive-4670 中文题面:https://www.luogu.org/problem/show?pid=3796 AC自动机模板 注意如 ...
- Mantis 从Windows 迁移到Linux上
1. 导出windows manits的mysql数据库文件, 在cmd运行:mysqldump -uroot -p3edc$RFV bugtracker > C:/mantis.sql; 2. ...
- HDFS不存在绝对路径,无法找到文件所在具体位置
This is set in the dfs.datanode.data.dir property, which defaults to file://${hadoop.tmp.dir}/dfs/da ...
- 【BZOJ4884】太空猫 [DP]
太空猫 Time Limit: 1 Sec Memory Limit: 256 MB[Submit][Status][Discuss] Description 太空猫(SpaceCat)是一款画面精 ...
- webpack 4 :从0配置到项目搭建
webpack4发布以来,我写项目都是用脚手架,即使再简单的项目,真的是really shame..虽然道听途说了很多 webpack4 的特性,却没有尝试过,因为它给人的感觉就是,em...很难.但 ...
- 01背包入门 dp
题目引入: 有n个重量和价值分别为Wi,Vi的物品.从这些物品中挑选出总重量不超过W的物品,求所有挑选方案中的价值总和的最大值. 分析: 首先,我们用最普通的方法,针对每个物品是否放入背包进行搜索. ...
- js_在原有的日期上添加天数输出添加后的日期
开始编码工作也有段时间了,想想没有留下点什么,有点遗憾.学到的一些经验,写写,分享一下.也给自己整理一下. 今天分享一下,在原有的日期上添加天数输出添加后的日期.开始做的时候,简单的思路是,直接用ne ...