题目链接:力扣 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;
}
};
通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。 ↩︎