📜  最大长度链对| DP-20(1)

📅  最后修改于: 2023-12-03 15:26:26.191000             🧑  作者: Mango

最大长度链对| DP-20

最大长度链对问题是指给定一组链对 (a, b),其中每个链对用两个数字表示,第一个数字代表链的起点,第二个数字代表链的终点。我们需要选出一组链对 (c, d),其中每个链对 (c, d) 满足 d < b 且 c > a。这样的链对组中链对的数量最多且链条长度最长。

动态规划解法

使用动态规划来解决最大长度链对问题。

定义一个DP数组,其中DP[i]表示以第i个链对结尾的最长链条长度。然后,对于每个链对i,我们需要查看其前面的所有链对j,其中 j < i 且 b[j] < a[i]。如果找到这样一个链对,那么DP[i]等于DP[j] + 1。这是因为将链对j添加到链对i之后,就可以创建一个新的链条。

最终答案是DP数组中的最大值。

以下是C++代码实现:

#include<bits/stdc++.h>
using namespace std;

bool comp(pair<int,int> a,pair<int,int> b)
{
    return a.second<b.second;
}

int maxChainLength(vector<pair<int,int>> &pairs) 
{
    int n=pairs.size();
    int dp[n];
    for(int i=0;i<n;i++)
        dp[i]=1;
        
    sort(pairs.begin(),pairs.end(),comp);
    for(int i=1;i<n;i++)
    {   
        for(int j=0;j<i;j++)
        {
            if(pairs[j].second<pairs[i].first)
            {
                dp[i]=max(dp[i],dp[j]+1);
            }
        }
    }
    
    int ans=INT_MIN;
    for(int i=0;i<n;i++)
        ans=max(ans,dp[i]);
        
    return ans;
}

int main()
{
    vector<pair<int,int>> pairs={{5,24},{15,25},{27,40},{50,60}};
    cout<<maxChainLength(pairs)<<endl;
    return 0;
}

以上代码的时间复杂度为O(n^2)。

贪心算法解法

最大长度链对问题也可以使用贪心算法来解决。

我们可以将链对按照其终点坐标从小到大排序,然后遍历每个链对,并且仅选择那些起点在当前链对终点之前的链对。

以下是C++代码实现:

#include<bits/stdc++.h>
using namespace std;

bool comp(pair<int,int> a,pair<int,int> b)
{
    return a.second<b.second;
}

int maxChainLength(vector<pair<int,int>> &pairs) 
{
    int n=pairs.size();
    int count=1;
    
    sort(pairs.begin(),pairs.end(),comp);
    int end=pairs[0].second;
    for(int i=1;i<n;i++)
    {
        if(pairs[i].first>end)
        {
            count++;
            end=pairs[i].second;
        }
    }
    return count;
}

int main()
{
    vector<pair<int,int>> pairs={{5,24},{15,25},{27,40},{50,60}};
    cout<<maxChainLength(pairs)<<endl;
    return 0;
}

以上代码的时间复杂度为O(nlogn)。