简单的区间覆盖问题
来源:互联网 发布:java代码换行符 编辑:程序博客网 时间:2024/05/17 01:38
问题描述:用i表示x轴上坐标为[i-1,i]的区间(区间长度为1),并给出M个不同的整数来表示M个这样的区间。现在要求画出几条线段覆盖住所有的区间,条件是:每条线段可任意长,但要求所画线段长度之和最小,并且线段的数目不超过N。
分析:
1) 整型数组p[M]表示所有从0开始的区间长度,假设p[M]已经按从小到大的顺序排好;
2) 如果N>=M,那么用 M条长度为 1 的线段可以覆盖住所有的区间,所求的线段总长为 M;
3)如果N<M,可以按照如下的贪心准则解决:
① 如果N=1,即要用一条线段覆盖住所有区间。
线段总长:p[M-1]-p[0]+1。
其中:p[0]=1 , p[1]=3 , p[2]=4 , ……,p[M-1]=M--区间总长度
② 如果N=2,即要用 2 条线段覆盖住所有区间,相当于把N=1中的线段分为两部分,各覆盖左、右区间。
如果线段在M个区间中不相邻的区间之间断开(如在p[0]与p[1]之间),这样总长度小于断开之前。【不相邻的很多怎么办?】
线段总长度减少: p[1]-p[0]-1
回顾我们的题目要求:求最小线段总长。
找到间隔最大的两个相邻区间,将之断开。
这一过程相当于找:d[i]=p[i]-p[i-1]-1(1<i<M)的最大值
如果N=3,相当于在N=2的方案下,将某条线段断成两截,并作可能的端点调整。
为了得到当前情况下最小的总长度,同样应该在间隔最大的两个相邻区间之间断开。
如果原来的方案是N=2时总长最小的方案,这一操作是N=3时总长最小的方案。
当N=k(k>1)时依此类推,只需在N=k-1时最小总长的覆盖方案下,找到被同一条线段覆盖的间隔最大的两个相邻区间
------“贪心”地从间隔处断开并调整两边线段的端点,就可以得到总长最小的方案
贪心策略就是每次从找到当前间隔最大的相邻区间
例题
用i来表示x坐标轴上坐标为[i-1,i]的长度为1的区间,并给出N(1≤N≤200)个不同的整数,表示N个这样的区间。
输入
输出
示例输入
5 31 3 5 8 11
示例输出
7
代码
#include <iostream>#include <algorithm>using namespace std;int a[1000];int s[1000];int cmp(int a,int b){ return a>b;}int main(){ int n,m; int len; int sum; while(cin>>n>>m) { for(int i=0;i<=n-1;i++) { cin>>a[i]; } sort(a,a+n); len=a[n-1]-a[0]+1; for(int i=0;i<n-1;i++)//求区间的间隔距离 { s[i]=a[i+1]-a[i]-1; } sort(s,s+n-1,cmp); sum=len; for(int i=0;i<m-1;i++) { sum=sum-s[i]; } cout << sum << endl; } return 0;}
整个过程说白了就是排序,没啥。
- 简单的区间覆盖问题
- 区间覆盖问题
- 区间覆盖问题
- 区间覆盖问题
- 区间覆盖问题
- 区间覆盖问题(sdut2074
- 区间覆盖问题
- 区间覆盖问题【贪心】
- 区间覆盖问题
- 【区间完全覆盖问题】
- 区间覆盖问题
- 区间覆盖问题 贪心
- 区间覆盖问题
- 贪心 区间覆盖问题
- 区间覆盖问题(贪心)
- 区间覆盖问题
- 区间覆盖问题
- 区间覆盖问题
- Generate Parentheses
- 设计模式(9):命令模式
- 广义表的head与tail的基本用法
- Struts基本开发搭建步骤-总结
- Debian Stable (Jessie 8.1) 的normal.mod not found
- 简单的区间覆盖问题
- 【HTML】常用跨域技术
- Android开发之路(二)--浅析MVC开发模式
- 设计模式——代理模式
- 如何禁止搜索引擎收录网站内容
- KE 时钟
- python简单爬虫例子(一)
- 详细描述求最长公共子序列算法
- 多进程、多线程、同步、通信