每日一题题解

题目链接:力扣 646. 最长数对链


题目大意

给出 n 个数对,设 [a,b] , [c,d] (a<b,c<d)为一对数对,当且仅当 b < c 的时候,[a,b] - > [c,d] ,形成数对链,数对可以以任意顺序排列,求出最长的数对链的长度(不必使用所有的数对)。(1<=n<=1000)

题意解析

首先附上官方题解

这个题目与力扣的300. 最长递增子序列的题目所使用的方法类似,可以使用动态规划1的方法解决。

图片写法参考自https://www.acwing.com/video/327/
动态规划
对于当前第 i 个数对,如果可以和之前的某一个数对 j 形成数对链,那么 dp[i] 就可以更新为 dp[i] 和 dp[j]+1 的较大值。(dp[j]+1 表示前面的数对链加上当前数对的个数)

if(p[i][0]>p[j][1])
{
    dp[i]=max(dp[i],dp[j]+1);
}

代码

class Solution {
public:
    int findLongestChain(vector<vector<int>>& p) 
    {
        sort(p.begin(),p.end()); //考虑到题目说的任意顺序,这里一定要排序
        vector<int> dp(p.size());
        for(int i=0;i<p.size();i++)
        {
            dp[i]=1; //其本身也算一个
            for(int j=0;j<i;j++)
            {
                if(p[i][0]>p[j][1])
                {//如果当前数对可以加在前面的数对链后面
                    dp[i]=max(dp[i],dp[j]+1);
                }
            }
        }

        int ans=0;//求出最大值
        for(auto x : dp) ans=max(ans,x);
        return ans;
    }
};

  1. 通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。 ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值