POJ 3171
题目大意:
给定一个区间范围[M,E],接下来有n行输入。每行输入三个数值:T1,T2,S,表示覆盖区间[T1,T2]
的代价为S,要求你求出覆盖区间[M,E]的最小代价,假设不能覆盖,则输出-1.
解题思路:
先将区间按右端点进行排序,这样我们就能得到dp状态的定义和转移方程:
dp[i]:表示覆盖[M,cow[i].T2]的最小覆盖代价.
dp[i] = cow[i].cost (cow[i].l == M) 或者 dp[i] = min(dp[j~i]) + cow[i].cost(cow[j].T2 >= cow[i].T1-1)
因为右端点可能有重合的情况,所以我们的dp[i]中可能存放的并非最小覆盖代价。当然了,
我们能够对右端点进行离散化。然后去重,这样dp数组里面存放的就是最优解,只是这添加了
编程的复杂度,代码量也加大不少.事实上,我们依旧能够用上述dp定义。最后dp[j~i]cow[j].T2==cow[i].T2)
的最小值就能够了.关于dp[i] = min(dp[j~i]) + cow[i].cost,是个RMQ问题,这里我用的是线段树实现的.
以下是解题代码。代码中对空间进行了优化。所以代码中并没有dp数组。其值都存放在线段树中.
#include<stdio.h>
#include<algorithm>
#define MAX_N 11000
#define INF 100000000000
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
struct Node
{
int l,r,c;
bool operator < (const Node &tmp) const
{
return r < tmp.r;
}
}cow[MAX_N];
long long tree[MAX_N<<2];
void build(int l,int r,int rt)
{
tree[rt] = INF ;
if( l == r)
return;
int m = l + ( r - l ) / 2 ;
build(lson);
build(rson);
}
long long query(int L,int R,int l,int r,int rt)
{
if(L <= l && r <= R)
return tree[rt];
int m = l + ( r - l ) / 2 ;
long long tmp = INF;
if(L <= m)
tmp = query(L,R,lson);
if(R > m)
tmp = min(tmp,query(L,R,rson));
return tmp;
}
void update(int pos,long long val,int l,int r,int rt)
{
if(l == r)
{
tree[rt] = val ;
return;
}
int m = l + ( r - l ) / 2 ;
if(pos <= m)
update(pos,val,lson);
else
update(pos,val,rson);
tree[rt] = min(tree[rt<<1],tree[rt<<1|1]);
}
//去掉不满足条件的区间
int init(int n)
{
int cnt = 0 , r_max = cow[0].r ;
for(int i=1;i<n;++i)
{
if(cow[i].r != cow[i-1].r)
r_max = cow[cnt].r ;
if(cow[i].l - 1 <= r_max)
cow[++cnt] = cow[i];
}
return cnt;
}
int Bin(int key,int l,int r)
{
while(l <= r)
{
int m = l + ( r - l ) / 2 ;
if(cow[m].r < key)
l = m + 1 ;
else
r = m - 1 ;
}
return l;
}
int main()
{
int n,m,e;
while(~scanf("%d%d%d",&n,&m,&e))
{
int l_min = 90000 , r_max = 0 ;
for(int i=0;i<n;++i)
{
scanf("%d%d%d",&cow[i].l,&cow[i].r,&cow[i].c);
l_min = min(l_min,cow[i].l);
r_max = max(r_max,cow[i].r);
}
sort(cow,cow+n);
n = init(n) ;
if(l_min > m || r_max < e || cow[n].r < e)
{
printf("-1\n");
continue;
}
build(0,n,1);
for(int i=0;i<=n;++i)
{
long long tmp;
if(cow[i].l == m)
tmp = (long long)cow[i].c ;
else
tmp = query(Bin(cow[i].l-1,0,i),i,0,n,1) + cow[i].c;
update(i,tmp,0,n,1);
}
printf("%I64d\n",query(Bin(cow[n].r,0,n),n,0,n,1));
}
return 0;
}
POJ 3171的更多相关文章
- POJ 3171 Cleaning Shifts(DP+zkw线段树)
[题目链接] http://poj.org/problem?id=3171 [题目大意] 给出一些区间和他们的价值,求覆盖一整条线段的最小代价 [题解] 我们发现对区间右端点排序后有dp[r]=min ...
- poj 3171 Cleaning Shifts(区间的最小覆盖价值)
Cleaning Shifts Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 2743 Accepted: 955 De ...
- POJ 3171 Cleaning Shifts
Description Farmer John's cows, pampered since birth, have reached new heights of fastidiousness. Th ...
- POJ 3171 DP
Cleaning Shifts Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 3563 Accepted: 1205 D ...
- POJ 3171.Cleaning Shifts-区间覆盖最小花费-dp+线段树优化(单点更新、区间查询最值)
Cleaning Shifts Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 4721 Accepted: 1593 D ...
- POJ 3171 区间最小花费覆盖 (DP+线段树
Cleaning Shifts Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 4245 Accepted: 1429 D ...
- POJ 3171 区间覆盖最小值&&线段树优化dp
Cleaning Shifts Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 4715 Accepted: 1590 D ...
- POJ 3370. Halloween treats 抽屉原理 / 鸽巢原理
Halloween treats Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 7644 Accepted: 2798 ...
- POJ 2356. Find a multiple 抽屉原理 / 鸽巢原理
Find a multiple Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 7192 Accepted: 3138 ...
随机推荐
- android4.0.3源码之USB wifi移植心得
http://blog.csdn.net/eastmoon502136/article/details/7850157 http://forum.cubietech.com/forum.php?mod ...
- Java中的阻塞队列(BlockingQueue)
1. 什么是阻塞队列 阻塞队列(BlockingQueue)是 Java 5 并发新特性中的内容,阻塞队列的接口是 java.util.concurrent.BlockingQueue,它提供了两个附 ...
- jquery post 同步异步总结
最近在测试,发现有些效果不对,最后发现是post的执行顺序问题,所以研究了下,写了以下总结 1.post被请求多次,解决方法: 连接加入随机数 rand=""+Math.rando ...
- markdown 表格宽度调整
先在浏览器中看看 HTML是怎样的: 看起来似乎不错.回到 Markdown 上,在原表格前添加 CSS 代码,类似这样: <style> table th:first-of-type ...
- HeadFirst 设计模式 04 工厂模式
除了 new 操作符之外, 还有更多创造对象的方法. 工厂处理创建对象的细节. 这么做的目的是为了抽象, 例如把创建比萨的代码包装进一个类, 当以后实现改变时, 只需修改这个类即可. 利用静态方法定义 ...
- java.lang下面有一个接口:Comparable(可比较的)
对于自定义对象,Sort不知道规则,所以无法比较.这种情况下一定要定义排序规则.方式有两种: java.lang下面有一个接口:Comparable(可比较的) 可以让自定义对象实现一个接口,这个接口 ...
- 【BZOJ】1693: [Usaco2007 Demo]Asteroids(匈牙利)
http://www.lydsy.com/JudgeOnline/problem.php?id=1693 裸匈牙利.. #include <cstdio> #include <cst ...
- javascript实现打印功能
<input name="b_print" type="button" class="ipt" onClick="print ...
- Windows下基于eclipse的Spark应用开发环境搭建
原创文章,转载请注明: 转载自www.cnblogs.com/tovin/p/3822985.html 一.软件下载 maven下载安装 :http://10.100.209.243/share/so ...
- WPF 在TextBox失去焦点时检测数据,出错重新获得焦点解决办法
WPF 在TextBox失去焦点时检测数据,出错重新获得焦点解决办法 在WPF的TextBox的LostFocus事件中直接使用Focus()方法会出现死循环的问题 正确的使用方式有2中方法: 方法一 ...