区间覆盖问题(贪心)
2017-04-08 22:51
696 查看
p1338区间覆盖问题(贪心之子问题)
子问题系列的贪心是一个很重要的贪心系列,可以用递归求解,虽然暂时不觉得会比普通循环好到哪里去
【问题描述】任务1:区间覆盖问题 数轴上有n闭区间[ai,bi],选择尽量少的区间覆盖一条指定线段[s,t]。
任务2:覆盖区间问题
数轴上有n闭区间[ai,bi],选择尽量少的闭区间[cj,dj]覆盖所有的闭区间[ai,bi],且[cj,dj]所包含的点不能有n个闭区间[ai,bi]之外的点。
这次贪心建立在左端点从左到右排序的基础上
问题一
先解决第一个问题,因为这是子问题系列的贪心:取一条右端点最右并且满足条件的线段,然后解决一个子问题,因此尝试递归(不一定最好)void f(int i,int s,int t,int ans)//求s到t的距离,选择第了ns个,从第i个开始考虑 状态怎么好写就怎么定义,不要太拘泥 { if(s>=t&&ans!=0)//有可能s=t { cout<<ans<<endl; return; } if(i==n+1)//排除无法覆盖情况1 { cout<<-1<<endl; return; } if(p[i].a>s)//中间断开的情况(主要) { cout<<-1<<endl; return; } int sub=i,j; for(j=i+1;j<=n;j++) { if(p[j].a<=s) if(p[j].b>p[sub].b) sub=j; else break; } f(j,p[sub].b,t,ans+1); }
这一段主要的问题就是判断无解比较考技术,不容易考虑到,会大家都会,但是通过率只有百分之二十
问题二
vector<data>v;//因为要先输出答案,因此只好想个办法存储 int a=p[1].a,b=p[1].b; for(int i=1;i<=n;i++) { if(p[i].a<=b) { b=max(b,p[i].b);//这里可以选取最好的右端 } else { v.push_back((data){a,b}); a=p[i].a; b=p[i].b; } } v.push_back((data){a,b});//因为最后一段无法加入,要手工,用哨兵就有点扯了 cout<<v.size()<<endl; for(int i=0;i<v.size();i++) { printf("%d %d\n",v[i].a,v[i].b); }
总结:这道题只是一个细节题,同时也有些新的手法值得积累,这个问题的类型倒是贪心中一个比较冷门的却有些难度的,顺便试试新开通的博客。。。
相关文章推荐
- UVA 10020 Minimal coverage 区间覆盖问题 贪心
- 区间覆盖问题(贪心)
- 步步为营(六)贪心(5)最小区间覆盖问题
- nyoj--12--喷水装置(二)(区间覆盖问题+贪心)
- 区间覆盖问题【贪心】
- 贪心 区间覆盖问题
- 喷水装置(二) +区间覆盖-基础问题-贪心
- FZU - 2144 Shooting Game(贪心,区间覆盖问题变题)
- 喷水装置(二)(南阳oj12)(贪心之区间覆盖问题)
- uva11134 线性区间覆盖问题(贪心模型+优先队列实现)
- SDUTOJ 2074 区间覆盖问题 贪心
- poj 1089 贪心之区间覆盖问题
- 区间覆盖问题(贪心)
- UVA 10020 Minimal coverage(贪心 + 区间覆盖问题)
- ACMjava经典贪心区间问题,区间选点,不相交区间,区间覆盖
- 区间覆盖问题(贪心)
- UVa 10382 - Watering Grass(贪心+区间覆盖问题)
- nyoj--12--喷水装置(二)(区间覆盖问题+贪心)
- 高效算法——D 贪心,区间覆盖问题
- 一个小贪心 区间覆盖问题