【问题标题】:Max length chain最大长度链条
【发布时间】:2020-05-16 15:11:13
【问题描述】:

给你 N 对数字。在每一对中,第一个数字总是小于第二个数字。如果 b

输入:
输入的第一行包含一个整数 T,表示测试用例的数量,然后是 T 个测试用例。然后是 T 个测试用例。输入的第一行包含一个整数 N 表示对数。下一行是 2*N 空格分隔的值,表示 N 对。

输出:
每个测试用例的输出将是形成的最长链的长度。

约束:

1<=T<=100
1<=N<=100

示例(仅用于预期输出):

输入

2
5
5  24 39 60 15 28 27 40 50 90
2
5 10 1 11 

输出

3
1
​

解释

(i) 给定的对是 {{5, 24}, {39, 60}, {15, 28}, {27, 40}, {50, 90} },可以形成的最长链是长度为 3,链为 {{5, 24}, {27, 40}, {50, 90}}

(ii) 可能的最大链长度仅为 1。

代码:

int maxChainLen(struct val p[],int n)
{
int dp[n];
dp[0]=1;
for(int i=1;i<=n;i++) {
    dp[i]=1;
   for(int j=0;j<i;j++) {
       if(p[j].second < p[i].first && dp[i]<dp[j]+1) {
           dp[i]=dp[j]+1;
       }
   }
}

int max=dp[0];
for(int i=0;i<n;i++) {
    if(dp[i]>max) {
        max=dp[i];
    }
}
return max;
}

算法:
与最长递增子序列相同,但条件改变((p[j].second

但是在提交时,一些测试用例失败了;这个算法哪里出错了?

以下测试用例失败:

34
778 887 794 916 336 387 493 650 363 422 28 691 60 764 541 927 173 427 212 737 369 568 430 783 531 863 68 124 136 930 23 803 59 70 168 394 12 457 43 230 374 422 785 920 199 538 316 325 371 414 92 527 957 981 863 874 171 997 282 306 85 926 328 337 506 847 314 730

Its Correct output is:
8

And Your Code's output is:
4

【问题讨论】:

  • 你有asked a rubber duck吗?
  • 这对我来说似乎是正确的,除非问题表明您可以按任何顺序选择配对。
  • 哪些测试用例失败了?我认为这是因为运行时的复杂性,大型测试失败了。
  • 您的算法假定dp 已经包含在第一个循环中在当前对之前结束的所有对的正确值。但是输入没有排序
  • 是的,算法假设; “输入未排序”意味着我们可以按任何顺序选择对,即 - 并不意味着在最大长度链中,如果第 j 对在第 i 对之前,那么在实际数组中 j

标签: algorithm data-structures array-algorithms longest-substring


【解决方案1】:

如果您将每一对视为实线上的一个区间,那么挑战是找到区间的Maximum Disjoint Set (MDS)。有一个相当知名的greedy algorithm 可以在O(nLgn) 中找到MDS。

关键是首先按它们的端点对它们进行排序。然后,对该算法的大多数解释都谈到从集合中删除重叠间隔,但这并不是真正必要的。相反,您可以遍历排序列表,并且仅在发现不相交的一对时才增加当前对。

L = list of n pairs (a, b), a < b, sorted by b
count = 1
curr = 0
for i = 1 to n-1
  if L(i).a > L(curr).b
    count = count + 1
    curr = i

然后由count给出结果

【讨论】:

    【解决方案2】:

    您在代码中的逻辑是错误的。例如,当i = 3, 比较所有对 (0,1)、(0,2)、(0,3) 时,您实际上只需要计算后续对。

    另外,您的解决方案过于复杂。你可以在O(n) 而不是O(n^2) 中解决这个问题。

    您可以通过一次解析找到答案。在每次迭代时,如果是链,您只需增加当前的dp[i]

    【讨论】:

    • 我附上了失败的测试用例。如果代码由于运行时限制而失败,那么它不应该显示 TIME LIMIT EXCEEDED 吗?
    • 对不起,我的坏忽略了细节。更新了我的答案,但不提供直接代码,因为我相信这对您自己编写代码真的很有帮助。
    猜你喜欢
    • 2017-12-15
    • 2014-08-07
    • 1970-01-01
    • 2016-07-13
    • 2015-07-18
    • 1970-01-01
    • 2010-09-15
    • 2014-10-03
    • 2011-11-06
    相关资源
    最近更新 更多