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 ...
随机推荐
- PHP——投票
要求: 选择第一个页面的复选框值,点击提交则提交数据,点击查看结果在同一页面覆盖显示结果的投票人数,百分比和进度条,点击返回,返回第一页面 数据库为 投票 表格为diaoyanxx 表格内容为: zh ...
- [ExtJS5学习笔记]第二十七节 CMD打包错误 Error C2009: YUI Parse Error (identifier is a reserved word => debugger;)
本文地址:http://blog.csdn.net/sushengmiyan/article/details/41242993 本文作者:sushengmiyan ------------------ ...
- EasyUI 创建Tree
tree可以被从标记创建.easyui tree应该定义在ul元素中.无序列表ul元素提供了基本tree结构.每一个li元素被产生一个tree节点,子ul元素产生父tree节点.例子: < ...
- cssText方式写入css
<div class="a" id="a">hello world</div> <script> //通过JS来覆写对象的样 ...
- List去重复(List中存的是对象)
class ProductComparare : IEqualityComparer<YEWULIANG> { private Func<YEWULIANG, object> ...
- UIView 坐标转换
例子1 Controller的view中有一个tableView,tableView的cell上有一个button,现在需要将button的frame转为在Controller的view中的frame ...
- 判断ActiveX控件是Desgin Mode还是Runtime Mode
对于MFC COleControl::AmbientUserMode Determines if the Container is in design mode or user mode. BOOL ...
- MVC模式 与 Model2模型 介绍
Model1回顾 MVC模式:MVC(Model.View.Controller)是软件开发过程中比较流行的设计思想.旨在分离模型.控制.师徒.是一种分层思想的体现. Model2简介Java Web ...
- win7显示方向旋转快捷键禁用及图形属性打开方法
方法/步骤 1 首先在桌面右键→打开[图形属性],如果没有,请看步骤2.如果有,直接进入步骤3 步骤阅读 2 为了美化桌面右键,往往会把桌面右键中的图形选项隐藏掉,此时,我们可以通过[控制面板]打 ...
- angular 封装公共方法
angular封装公共方法到service中间件,节省开发时间 layer.service.ts openAlert(callback) {// 传递回调函数 const dialogRef = th ...