P4644 [Usaco2005 Dec]Cleaning Shifts 清理牛棚
P4644 [Usaco2005 Dec]Cleaning Shifts 清理牛棚
你有一段区间需要被覆盖(长度 <= 86,399)
现有 \(n \leq 10000\) 段小线段, 每段可以从 \(l_{i}\) 到 \(r_{i}\) 花费为 \(s_{i}\)
求覆盖整个区间的最小花费
错误日志: 初始化时应该是 \(dp[L - 1]\) 为 \(0\) 而不是 \(dp[1]\) 为 \(0\) , 因为只需要覆盖 \([L, R]\)
Solution
设 \(dp[n]\) 表示从起点覆盖到 \(n\) 的最小花费
我们将小线段按照右端点升序排序, 满足无后效性
对于第 \(i\) 个线段, 有状态转移方程:$$dp[r_{i}] = min(dp[r_{i}], \min_{l_[i] - 1 \leq k < r_{i}}dp[k] + s_{i})$$
其含义为: 从第 \(i\) 段线段的起点开始选择上一个终点的最小值, 这样可以使线段相交(来保证无空白), 更新此线段能覆盖的终点
然后发现我们需要区间查询最小值和单点修改
为啥是单点修改不是区间修改呢? 当两个线段相交, 一定有 \(l_{x} \leq r_{y}\)
所以只需要在线段终点处单点修改即可
初始化 \(dp[L - 1]\) 为零
因为需要线段树维护, 尽量把起点设为 \(1\) 防止各种奇怪的错误, 本题所有位置点坐标 $ + 2$
还要注意处理一下超出 \([L, R]\) 的线段
Code
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
#include<climits>
#define LL long long
#define REP(i, x, y) for(int i = (x);i <= (y);i++)
using namespace std;
int RD(){
    int out = 0,flag = 1;char c = getchar();
    while(c < '0' || c >'9'){if(c == '-')flag = -1;c = getchar();}
    while(c >= '0' && c <= '9'){out = out * 10 + c - '0';c = getchar();}
    return flag * out;
    }
const int minn = 166419, INF = 1e9;
int num, L, R;
struct Node{
	int l, r, s;
	}I[minn];
bool cmp(Node a, Node b){return a.r < b.r;}
#define lid (id << 1)
#define rid (id << 1) | 1
int dp[minn];
struct seg_tree{
	int l, r;
	int min;
	}tree[minn << 2];
void pushup(int id){tree[id].min = min(tree[lid].min, tree[rid].min);}
void build(int id, int l, int r){
	tree[id].l = l, tree[id].r = r;
	if(l == r){
		tree[id].min = dp[l];
		return ;
		}
	int mid = (l + r) >> 1;
	build(lid, l, mid), build(rid, mid + 1, r);
	pushup(id);
	}
void update(int id, int val, int l, int r){
	if(tree[id].l == l && tree[id].r == r){
		tree[id].min = val;
		return ;
		}
	int mid = (tree[id].l + tree[id].r) >> 1;
	if(mid < l)update(rid, val, l, r);
	else update(lid, val, l, r);
	pushup(id);
	}
int query(int id, int l, int r){
	if(tree[id].l == l && tree[id].r == r)return tree[id].min;
	int mid = (tree[id].l + tree[id].r) >> 1;
	if(mid < l)return query(rid, l, r);
	else if(mid >= r)return query(lid, l, r);
	else return min(query(lid, l, mid), query(rid, mid + 1, r));
	}
int main(){
	num = RD(), L = RD() + 2, R = RD() + 2;//保证线段树左端点是1
	REP(i, 1, R)dp[i] = INF;
	dp[L - 1] = 0;
	build(1, 1, R);
	REP(i, 1, num){
		I[i].l = RD() + 2;
		I[i].r = RD() + 2;
		I[i].s = RD();
		I[i].l = I[i].l < L ? L : I[i].l;//处理一下超出范围的
		I[i].r = I[i].r > R ? R : I[i].r;
		}
	sort(I + 1, I + 1 + num, cmp);
	REP(i, 1, num){
		int minn = query(1, I[i].l - 1, I[i].r);
		//printf("minn=%d\n", minn);
		dp[I[i].r] = min(dp[I[i].r], minn + I[i].s);
		update(1, dp[I[i].r], I[i].r, I[i].r);
		}
	//REP(i, L - 1, R)printf("dp[%d]=%d\n", i - 2, dp[i]);
	if(dp[R] == INF){puts("-1");return 0;}
	printf("%d\n", dp[R]);
	return 0;
	}
P4644 [Usaco2005 Dec]Cleaning Shifts 清理牛棚的更多相关文章
- 洛谷P4644 [USACO2005 Dec]Cleaning Shifts 清理牛棚 [DP,数据结构优化]
		题目传送门 清理牛棚 题目描述 Farmer John's cows, pampered since birth, have reached new heights of fastidiousness ... 
- BZOJ1672: [Usaco2005 Dec]Cleaning Shifts 清理牛棚
		1672: [Usaco2005 Dec]Cleaning Shifts 清理牛棚 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 414 Solved: ... 
- BZOJ 1672: [Usaco2005 Dec]Cleaning Shifts 清理牛棚
		题目 1672: [Usaco2005 Dec]Cleaning Shifts 清理牛棚 Time Limit: 5 Sec Memory Limit: 64 MB Description Farm ... 
- BZOJ_1672_[Usaco2005 Dec]Cleaning Shifts 清理牛棚_动态规划+线段树
		BZOJ_1672_[Usaco2005 Dec]Cleaning Shifts 清理牛棚_动态规划+线段树 题意: 约翰的奶牛们从小娇生惯养,她们无法容忍牛棚里的任何脏东西.约翰发现,如果要使这群 ... 
- [Usaco2005 Dec]Cleaning Shifts 清理牛棚 (DP优化/线段树)
		[Usaco2005 Dec] Cleaning Shifts 清理牛棚 题目描述 Farmer John's cows, pampered since birth, have reached new ... 
- 【BZOJ1672】[Usaco2005 Dec]Cleaning Shifts 清理牛棚 动态规划
		[BZOJ1672][Usaco2005 Dec]Cleaning Shifts Description Farmer John's cows, pampered since birth, have ... 
- 【bzoj1672】[USACO2005 Dec]Cleaning Shifts 清理牛棚
		题目描述 Farmer John's cows, pampered since birth, have reached new heights of fastidiousness. They now ... 
- 【BZOJ】1672: [Usaco2005 Dec]Cleaning Shifts 清理牛棚(dp/线段树)
		http://www.lydsy.com/JudgeOnline/problem.php?id=1672 dp很好想,但是是n^2的..但是可以水过..(5s啊..) 按左端点排序后 f[i]表示取第 ... 
- 【bzoj1672】[USACO2005 Dec]Cleaning Shifts 清理牛棚  dp/线段树
		题目描述 Farmer John's cows, pampered since birth, have reached new heights of fastidiousness. They now ... 
随机推荐
- PSP Daily新增功能说明书
			1.选择输入类别时可以记录原来的输入,支持用户选择记录清空功能 2.添加“恢复最近”button,点击这个按钮可以跳出一个页面显示最近的excel记录,用户可以通过勾选相应的excel文件名,恢复选中 ... 
- SQLyog的基本使用
			[简介] SQLyog是mysql数据库的客户端软件 [基本使用] 1.连接mysql数据库 2.SQLyog的页面使用介绍 3.基本的数据库命令 1) use命令 切换数据库 2) unsigned ... 
- 【每日scrum】第一次冲刺day5
			请教以前做过类似软件的同学,受益匪浅,启发自己 
- Hibernate笔记②--hibernate类生成表、id生成策略、级联设置、继承映射
			一.多表的一个关联关系 老师和学生是一对多的关系 student:tid属性 外键约束 对应teacher表中的id属性 teacher:id 在myeclipse的db窗口中选中两个表来生成类. ... 
- 【TCP/IP详解 卷一:协议】第六章:DHCP 和自动配置
			简介 为了使用 TCP/IP 协议族,每台主机or路由器都需要一定的配置信息: IP地址 子网掩码 广播地址 路由或转发表 DNS 协议配置方法: 手动 通过使用网络服务来获得 使用一些算法来自动确定 ... 
- JDBC连接数据库代码和步骤
			JDBC连接数据库 创建一个以JDBC连接数据库的程序,包含7个步骤: 1.加载JDBC驱动程序 在连接数据库之前,首先要加载想要连接的数据库的驱动,这通过java.lang.Class类的静态方法 ... 
- Redis4.0 主从复制(PSYN2.0)
			Redis4.0版本相比原来3.x版本,增加了很多新特性,如模块化.PSYN2.0.非阻塞DEL和FLUSHALL/FLUSHDB.RDB-AOF混合持久化等功能.尤其是模块化功能,作者从七年前的re ... 
- dubbo面向服务使用
			首先启动zookeeper dubbo集群,使用两个dubbo,一个服务,一个调用,使用zookeeper管理 zeekeeper的功能:管理集群,保证集群成员的数据一致性和动作的协调 服务端: se ... 
- grunt入门讲解2:如何使用 Gruntfile 配置任务
			Grunt的task配置都是在 Gruntfile 中的grunt.initConfig方法中指定的.此配置主要包括以任务名称命名的属性,和其他任意数据.一旦这些代表任意数据的属性与任务所需要的属性相 ... 
- 【Linux笔记】ps、kill、netstat、nohup、screen
			1.ps 命令,用于查看当前正在运行的进程,使用该命令可以确定有哪些进程正在运行和运行的状态.进程是否结束.进程有没有僵尸.哪些进程占用了过多的资源等等. 语法: ps [options] 示例: p ... 
