Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 寻找区间的最大子集_Algorithm_Puzzle - Fatal编程技术网

Algorithm 寻找区间的最大子集

Algorithm 寻找区间的最大子集,algorithm,puzzle,Algorithm,Puzzle,我试图解决这个问题 此外,张贴问题:你会得到一个N个间隔的列表。 挑战在于选择区间的最大子集,使得子集中没有三个区间共享一个公共点 但无法找到解决方案。这就是我迄今为止所尝试的: DP:不要认为问题有重叠的子问题,所以这不起作用 将其简化为一个图,每个点都是一个顶点,区间是无向图的边。然后问题归结为在图中寻找最大长度不相交的路径。不能想出一个简洁的方法来做这件事 尝试将其减少到网络流量,但效果不佳 你们能给我一些关于如何解决这个问题的提示吗?或者我是否遗漏了什么。很抱歉,我做了很长一段时间的算法

我试图解决这个问题

此外,张贴问题:你会得到一个N个间隔的列表。 挑战在于选择区间的最大子集,使得子集中没有三个区间共享一个公共点

但无法找到解决方案。这就是我迄今为止所尝试的:

  • DP:不要认为问题有重叠的子问题,所以这不起作用
  • 将其简化为一个图,每个点都是一个顶点,区间是无向图的边。然后问题归结为在图中寻找最大长度不相交的路径。不能想出一个简洁的方法来做这件事
  • 尝试将其减少到网络流量,但效果不佳

  • 你们能给我一些关于如何解决这个问题的提示吗?或者我是否遗漏了什么。很抱歉,我做了很长一段时间的算法,最近失去了联系。

    我将用一般的语言给出解决方案,而不进行编程

    让我们将段表示为s1、s2、…、sn。它们的起点是b1,b2,。。。bn,其末端为e1,e2,。。。嗯

    根据片段的起始点对其进行排序,因此b1
    #include <iostream>
    #include <set>
    
    using namespace std;
    
    class Interval{
    public:
    int begin;int end;
    Interval(){
        begin=0;end=0;
    }
    
    Interval(int _b,int _e){
        begin=_b;end=_e;
    }
    
     bool operator==(const Interval& i) const {
         return (begin==i.begin)&&(end==i.end);
     }
    
     bool operator<(const Interval& i) const {
         return begin<i.begin;
     }
    };
    
    int n,t,a,b;
    multiset<Interval> inters;
    multiset<int> iends;
    
    multiset<Interval>::iterator it1;
    multiset<int>::iterator et1;
    
    int main(){
    scanf("%d",&t);
    while(t--){
        inters.clear();
        iends.clear();
        scanf("%d",&n);
        while(n--){
            scanf("%d %d",&a,&b);
            Interval inter(a,b);
            inters.insert(inter);
        }
        it1=inters.begin();
        while(it1!=inters.end()){
            iends.insert(it1->end);
            et1=iends.lower_bound(it1->begin);
            multiset<int>::iterator t=et1;
            if((++et1!=iends.end())&&(++et1!=iends.end())){
                //把剩下的线段全部删掉
                while(et1!=iends.end()){
                    multiset<int>::iterator te=et1;
                    et1++;
                    iends.erase(te);
                }
            }
            it1++;
        }
        printf("%d\n",iends.size());
    }
    system("pause");
    return 0;
    }
    
    #包括
    #包括
    使用名称空间std;
    课间休息{
    公众:
    int开始;int结束;
    间隔(){
    开始=0;结束=0;
    }
    间隔(整数b,整数e){
    开始=_b;结束=_e;
    }
    布尔运算符==(常数间隔和i)常数{
    返回(begin==i.begin)&(end==i.end);
    }
    布尔运算器;
    multiset::迭代器t=et1;
    如果(++et1!=iends.end())&&(++et1!=iends.end()){
    //把剩下的线段全部删掉
    while(et1!=iends.end()){
    multiset::迭代器te=et1;
    et1++;
    删除(te);
    }
    }
    it1++;
    }
    printf(“%d\n”,iends.size());
    }
    系统(“暂停”);
    返回0;
    }
    
    听起来像是段树的作业。这听起来像是一个调度问题。好吧,如果我错了,请纠正我,但假设我有这些段(1-2)、(1-3)、(1-10)、(3-5)、(3-6),那么根据此算法,解决方案应该是(1-2)、(1-3)、(3-5),但更好的解决方案可能是(1-10)、(1-2)、(3-5)(3-6)@user352951在您的示例中(1-10),(3-5)和(3-6)重叠