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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/25.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
C++ 美丽的人-动态规划_C++_Algorithm_Dynamic Programming - Fatal编程技术网

C++ 美丽的人-动态规划

C++ 美丽的人-动态规划,c++,algorithm,dynamic-programming,C++,Algorithm,Dynamic Programming,我试着解决美女问题,但在一些测试案例中我得到了错误的答案 一个城市中最负盛名的体育俱乐部有N名会员。 它的每一个成员都强壮美丽。更准确地说,i-th 本俱乐部会员(会员按入会时间编号) 俱乐部)有实力和美貌。因为这是一个非常重要的问题 享有盛誉的俱乐部,其成员非常富有,因此 不平凡的人,所以他们常常非常憎恨对方。 严格地说,X先生讨厌俱乐部的第j位成员 伊夫斯先生俱乐部≤ Sj和Bi≥ Bj或if Si≥ Sj和Bi≤ Bj(如果 Mr X的两个性质都大于的相应性质 Y先生,他甚至没有注意到他,

我试着解决美女问题,但在一些测试案例中我得到了错误的答案

一个城市中最负盛名的体育俱乐部有N名会员。 它的每一个成员都强壮美丽。更准确地说,i-th 本俱乐部会员(会员按入会时间编号) 俱乐部)有实力和美貌。因为这是一个非常重要的问题 享有盛誉的俱乐部,其成员非常富有,因此 不平凡的人,所以他们常常非常憎恨对方。 严格地说,X先生讨厌俱乐部的第j位成员 伊夫斯先生俱乐部≤ Sj和Bi≥ Bj或if Si≥ Sj和Bi≤ Bj(如果 Mr X的两个性质都大于的相应性质 Y先生,他甚至没有注意到他,另一方面,如果他的两个 财产较少,他非常尊敬Y先生)

为了庆祝新的2003年,俱乐部的管理层 计划组织一次聚会。但是他们担心如果两个 互相憎恨的人会在聚会结束后同时参加聚会 喝一两杯他们就会打架。所以没有两个讨厌的人 应该互相邀请。另一方面,为了保住俱乐部 普雷斯蒂≥ 在适当的层面上,政府希望邀请 尽可能多的人

作为政府中唯一一个不怕碰的人 一台电脑,你要写一个程序,找出该找谁 邀请参加聚会

输入

输入文件的第一行包含整数N—输入文件的编号 俱乐部成员。( 2 ≤ N≤ 100,000 ). 接下来的N行包含两个 每个编号分别为Si和Bi(1≤ 是,比≤ 10^9)

输出

在输出文件的第一行,打印最大数量的 可以被邀请参加聚会的人。在第二行上输出N 整数-以任意顺序邀请的成员数。如果 存在多个解决方案,输出任意一个

基本上,我的方法是:

  • 首先将数组强度[]按美丽[]排序
  • 获取一个数组D[i],该数组存储max lis直到i
  • 最优解=
    D(i)={1+Max(D(j))}
    其中
    j
    D[i]=Max{D[j]+1}
    用于
    j
    Strength[j]
    Beauty[j],如果没有这样的j,那么
    D(i)=1
  • 我的方法有什么遗漏吗

    我的解决方案:

    #include <iostream>
    #include <vector>
    #include <algorithm>
    using namespace std; 
    typedef struct {
        long int s;
        long int b;
    } c_type;
    int compare(const c_type &a, 
            const c_type &b) {
        return a.s < b.s;
    }
    
    int main( )
    {
    
    
    int n = 0;
    cin>>n;
    vector<c_type> ct;
    ct.resize(n);
    //vector<long int> b(n,-1);
    //s[0] = 1;
    //s[1] = 1;
    //s[2] = 2;
    //s[3] = 2;
    //b[0] = 1;
    //b[1] = 2;
    //b[2] = 1;
    //b[3] = 2;
    
    vector<long int> d(n,1);
    vector<long int> p(n,-1);
    long int max = -1;
    long int bestEnd = -1;
    for(int i = 0 ;i<n;i++)
    {
        cin>>ct[i].s>>ct[i].b;
    }
     sort (ct.begin(), ct.end(), compare);
    for(int i  = 1 ; i < n ;i++)
    {
        for(int j  = i-1 ; j>=0 ; j--)
        {
            if(((d[j] + 1) > d[i]) and (ct[j].b < ct[i].b) and (ct[j].s < ct[i].s))
            {
                d[i] = d[j]+1;
                p[i] = j;
            }
        }
        if(max < d[i])
        {
            max = d[i];
            bestEnd = i;
        }
    }
    cout<<max<<endl;
    if(bestEnd != -1)
    while(bestEnd not_eq -1)
    {
        cout<<bestEnd+1<<" ";
        bestEnd = p[bestEnd];
    }
    return 0;
    }
    
    #包括
    #包括
    #包括
    使用名称空间std;
    类型定义结构{
    长整数s;
    长int b;
    }c_型;
    整数比较(常数c_类型和a,
    常数c_类型和b){
    返回a.s>n;
    矢量ct;
    ct.resize(n);
    //向量b(n,-1);
    //s[0]=1;
    //s[1]=1;
    //s[2]=2;
    //s[3]=2;
    //b[0]=1;
    //b[1]=2;
    //b[2]=1;
    //b[3]=2;
    向量d(n,1);
    向量p(n,-1);
    长整型最大值=-1;
    长整型最佳结束=-1;
    对于(int i=0;i>ct[i].s>>ct[i].b;
    }
    排序(ct.begin(),ct.end(),compare);
    对于(int i=1;i=0;j--)
    {
    如果((d[j]+1)>d[i])和(ct[j].bcout因此,有一种有趣的方法从几何角度来思考这个问题。想象一下,绘制一个轴上有S,B的图形,并为每个人放置一个x。(也移除任何重复点,即,如果S=S和B=B,您可以移除其中一个)

    然后,对于每个点/人,只有矩形中较低和左侧的点才是可行的选择。因此,我可以将代表尊重他们的人数的数字与每个人关联。称这个数字为C

    这为a*搜索提供了一个可接受的启发式。从右上角的根节点开始,我的“最佳”move通常是具有最高C数的分支,因为它为以后保留了最多的选项。此外,一旦我找到了树底部的一个根,如果其他分支的C数高于实际人数,我只需要选择其他分支,因此树的大多数分支将很快终止

    我怀疑这种类型的搜索平均来说是最优的,但根据点的分布,它可能有缓慢的边缘情况

    这说明了它是如何工作的,从某个根节点开始,在第一次运行时,它会到达最高的C数,当它终止时,它会倒计时以提供一个“答案”,因此它只需检查C编号严格大于当前最佳答案的分支。在这种情况下,没有其他分支


    直观地很容易看出,如果点在S和B中均匀分布,这可能会非常快,但如果它们在y=x附近强烈聚集,这可能会非常慢,因为这样通常不会很快排除分支。

    您的解决方案为人员输出不正确的索引。当您对输入进行排序时,他们的排序会改变只需将额外的索引存储到您的结构中并使用它。

    但是,您的代码将得到TLE,这是O(N^2)的原因。您需要O(NlogN)解决方案,这是LIS的经典解决方案。

    这是LIS(最长递增子序列),您的解决方案似乎还可以。假设您有实现错误?(您可以在此处发布解决方案)@juver我已更新我的解决方案。您的解决方案为人员输出了不正确的索引。当您对输入进行排序后,他们的顺序发生了变化。只需将其他索引存储到您的结构中并使用它。但是,您将编写TLE,原因是O(N^2)。您需要O(NlogN)解决方案,这是LIS的经典解决方案。@尤文图斯您应该将此作为答案发布。对于OP,除了尤文图斯所说的,如果可以邀请的最大可能成员数为1,您也不能正确输出。俱乐部中的每个人
    #include <iostream>
    #include <vector>
    #include <algorithm>
    using namespace std; 
    typedef struct {
        long int s;
        long int b;
    } c_type;
    int compare(const c_type &a, 
            const c_type &b) {
        return a.s < b.s;
    }
    
    int main( )
    {
    
    
    int n = 0;
    cin>>n;
    vector<c_type> ct;
    ct.resize(n);
    //vector<long int> b(n,-1);
    //s[0] = 1;
    //s[1] = 1;
    //s[2] = 2;
    //s[3] = 2;
    //b[0] = 1;
    //b[1] = 2;
    //b[2] = 1;
    //b[3] = 2;
    
    vector<long int> d(n,1);
    vector<long int> p(n,-1);
    long int max = -1;
    long int bestEnd = -1;
    for(int i = 0 ;i<n;i++)
    {
        cin>>ct[i].s>>ct[i].b;
    }
     sort (ct.begin(), ct.end(), compare);
    for(int i  = 1 ; i < n ;i++)
    {
        for(int j  = i-1 ; j>=0 ; j--)
        {
            if(((d[j] + 1) > d[i]) and (ct[j].b < ct[i].b) and (ct[j].s < ct[i].s))
            {
                d[i] = d[j]+1;
                p[i] = j;
            }
        }
        if(max < d[i])
        {
            max = d[i];
            bestEnd = i;
        }
    }
    cout<<max<<endl;
    if(bestEnd != -1)
    while(bestEnd not_eq -1)
    {
        cout<<bestEnd+1<<" ";
        bestEnd = p[bestEnd];
    }
    return 0;
    }