题目大意:


       给定一个区间范围[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的更多相关文章

  1. POJ 3171 Cleaning Shifts(DP+zkw线段树)

    [题目链接] http://poj.org/problem?id=3171 [题目大意] 给出一些区间和他们的价值,求覆盖一整条线段的最小代价 [题解] 我们发现对区间右端点排序后有dp[r]=min ...

  2. poj 3171 Cleaning Shifts(区间的最小覆盖价值)

    Cleaning Shifts Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2743   Accepted: 955 De ...

  3. POJ 3171 Cleaning Shifts

    Description Farmer John's cows, pampered since birth, have reached new heights of fastidiousness. Th ...

  4. POJ 3171 DP

    Cleaning Shifts Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3563   Accepted: 1205 D ...

  5. POJ 3171.Cleaning Shifts-区间覆盖最小花费-dp+线段树优化(单点更新、区间查询最值)

    Cleaning Shifts Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4721   Accepted: 1593 D ...

  6. POJ 3171 区间最小花费覆盖 (DP+线段树

    Cleaning Shifts Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4245   Accepted: 1429 D ...

  7. POJ 3171 区间覆盖最小值&&线段树优化dp

    Cleaning Shifts Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4715   Accepted: 1590 D ...

  8. POJ 3370. Halloween treats 抽屉原理 / 鸽巢原理

    Halloween treats Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7644   Accepted: 2798 ...

  9. POJ 2356. Find a multiple 抽屉原理 / 鸽巢原理

    Find a multiple Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7192   Accepted: 3138   ...

随机推荐

  1. android4.0.3源码之USB wifi移植心得

    http://blog.csdn.net/eastmoon502136/article/details/7850157 http://forum.cubietech.com/forum.php?mod ...

  2. Java中的阻塞队列(BlockingQueue)

    1. 什么是阻塞队列 阻塞队列(BlockingQueue)是 Java 5 并发新特性中的内容,阻塞队列的接口是 java.util.concurrent.BlockingQueue,它提供了两个附 ...

  3. jquery post 同步异步总结

    最近在测试,发现有些效果不对,最后发现是post的执行顺序问题,所以研究了下,写了以下总结 1.post被请求多次,解决方法: 连接加入随机数 rand=""+Math.rando ...

  4. markdown 表格宽度调整

    先在浏览器中看看 HTML是怎样的:   看起来似乎不错.回到 Markdown 上,在原表格前添加 CSS 代码,类似这样: <style> table th:first-of-type ...

  5. HeadFirst 设计模式 04 工厂模式

    除了 new 操作符之外, 还有更多创造对象的方法. 工厂处理创建对象的细节. 这么做的目的是为了抽象, 例如把创建比萨的代码包装进一个类, 当以后实现改变时, 只需修改这个类即可. 利用静态方法定义 ...

  6. java.lang下面有一个接口:Comparable(可比较的)

    对于自定义对象,Sort不知道规则,所以无法比较.这种情况下一定要定义排序规则.方式有两种: java.lang下面有一个接口:Comparable(可比较的) 可以让自定义对象实现一个接口,这个接口 ...

  7. 【BZOJ】1693: [Usaco2007 Demo]Asteroids(匈牙利)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1693 裸匈牙利.. #include <cstdio> #include <cst ...

  8. javascript实现打印功能

    <input name="b_print" type="button" class="ipt" onClick="print ...

  9. Windows下基于eclipse的Spark应用开发环境搭建

    原创文章,转载请注明: 转载自www.cnblogs.com/tovin/p/3822985.html 一.软件下载 maven下载安装 :http://10.100.209.243/share/so ...

  10. WPF 在TextBox失去焦点时检测数据,出错重新获得焦点解决办法

    WPF 在TextBox失去焦点时检测数据,出错重新获得焦点解决办法 在WPF的TextBox的LostFocus事件中直接使用Focus()方法会出现死循环的问题 正确的使用方式有2中方法: 方法一 ...