楼主: wwwyhx
跳转到指定楼层
上一主题 下一主题
收起左侧

Ananimous(2) 找出得分最高的无重复子段

 
🔗
darksteel 2011-4-20 10:46:07 | 只看该作者
全局:
回复 20# vvnesaa
额,这个不好这么说吧,因为元素是在不断加入进来的,每次必须以logn的复杂度来维护才能不影响整体的复杂度,如果每次都排序不就变成n*nlogn了,每次直接插入新元素也会使复杂度变为n^2。所以我觉得第一个堆应该是非常必要的


   
回复

使用道具 举报

🔗
 楼主| wwwyhx 2011-4-20 11:32:27 | 只看该作者
全局:
本帖最后由 wwwyhx 于 2011-4-20 11:33 编辑

对的~
那个插入顺序。。。
你这么想:
[1, 5], [2, 3]算好了,现在要算[4, 6]
那么按end从小到大排,[ ...
vvnesaa 发表于 2011-4-20 10:23


MM是不是想复杂了,下面是我的思路,DP,无需而外空间(非极端情况下是nLogn时间,O(1)空间):

Sort the segments by  ending points says B
Look for B from beginning to the end, for each new segment, decide whether to add
it or not. TotalScore(n) = max{TotalScore(n-1), TotalScore(m)+Score(n)}, m is the
max number that do not overlapped with nth segment which means m+1 to n-m are overlapped with n(th) segment

极端情况时间复杂度是n^2,就是n个段互相重合
回复

使用道具 举报

🔗
vvnesaa 2011-4-20 11:55:11 | 只看该作者
全局:
回复  vvnesaa
额,这个不好这么说吧,因为元素是在不断加入进来的,每次必须以logn的复杂度来维护才能不 ...
darksteel 发表于 2011-4-20 10:46


囧。。。不好意思偶说错了。。。
根本不需要我说的那个堆。。。
直接记可能的最大值就好了@@
我太弱了。。。。@@
回复

使用道具 举报

🔗
darksteel 2011-4-20 11:56:53 | 只看该作者
全局:
回复 22# wwwyhx
感觉这个和dp有点类似,如果dp的时候按end从小到大排序,应该就是你这个意思。我再想如果你找m的时候用上二分,是不是可以降到nlogn呢?那位MM的方法我终于弄明白了,也是相当巧妙的

   
回复

使用道具 举报

🔗
darksteel 2011-4-20 12:02:09 | 只看该作者
全局:
回复 23# vvnesaa
啊!是这样,没错没错,原来你说的那一个堆就是指维护end的堆,这下全清楚了。。哪里,我感觉您编程和思维能力都很强,周围很少有这么厉害的女生。绝没有瞧不起女生的意思,只不过女生一般涉及coding都会有点头痛

   
回复

使用道具 举报

🔗
Imbalism 2011-4-20 12:03:33 | 只看该作者
全局:
MM是不是想复杂了,下面是我的思路,DP,无需而外空间(非极端情况下是nLogn时间,O(1)空间):

Sort ...
wwwyhx 发表于 2011-4-20 11:32


我也是这样理解的. 那么如何找到max m使得m.end < n.start? 线性查找的话平均case总时间是O(n^2), 如果用二分查找在1 to n-1 里面查找的话, 平均case和极端case的时间可以变为O(nlogn)   不知道这样分析和理解对不对, 代码稍后发上.
回复

使用道具 举报

🔗
Etrnls 2011-4-20 12:04:31 | 只看该作者
全局:
本帖最后由 Etrnls 于 2011-4-20 12:06 编辑


  1. sort(sortStart.begin(), sortStart.end(), [](int a, int b) { return seg[a].start < seg[b].start; } );
  2. sort(sortEnd.begin(), sortEnd.end(), [](int a, int b) { return seg[a].end < seg[b].end; } );

  3. f[0] = 0;
  4. for (int i = 1, j = 1, maxf = 0; i <= n; ++i)
  5. {
  6.     while (j < i && seg[sortEnd[j]].end < seg[sortStart[i]].start)
  7.     {
  8.         if (f[j] > maxf)    maxf = f[j];
  9.         ++j;
  10.     }
  11.     f[i] = max(f[i - 1], maxf + seg[sortStart[i]].score);
  12. }
复制代码
回复

使用道具 举报

🔗
 楼主| wwwyhx 2011-4-20 12:42:37 | 只看该作者
全局:
我也是这样理解的. 那么如何找到max m使得m.end < n.start? 线性查找的话平均case总时间是O(n^2), 如果 ...
Imbalism 发表于 2011-4-20 12:03


这个找m就是直接往后找就可以啦,如果新段覆盖的范围大就多找点,当然不嫌麻烦还是可以用二分,不过我觉得到这一步就够了。O(n^2)是极端的情况,平均时间复杂度因该还是nlogn。就像我们说的快速排序,说时间复杂度是O(nlogn)指的也是平均时间复杂度,最坏情况下快速排序时间复杂度还是O(n^2)
回复

使用道具 举报

🔗
 楼主| wwwyhx 2011-4-20 12:43:59 | 只看该作者
全局:
囧。。。不好意思偶说错了。。。
根本不需要我说的那个堆。。。
直接记可能的最大值就好了@@
我太弱 ...
vvnesaa 发表于 2011-4-20 11:55


这个MM还是很厉害的,大家记住他的ID
回复

使用道具 举报

🔗
Imbalism 2011-4-20 21:11:20 | 只看该作者
全局:
本帖最后由 Imbalism 于 2011-4-20 21:12 编辑

我的代码, 方法如前楼所述
  1. #include <iostream>
  2. #include <algorithm>
  3. #include <vector>
  4. #include <limits>
  5. #include <assert.h>
  6. using namespace std;


  7. const int MIN = numeric_limits<int>::min();


  8. struct Node
  9. {
  10.      int start;
  11.      int end;
  12.      int value;
  13. };


  14. bool compare(const Node& a, const Node& b)
  15. {
  16.      return a.end < b.end;
  17. }


  18. int max(int a, int b)
  19. {
  20.      return a > b ? a : b;
  21. }




  22. //if t is not found in the array a
  23. //return the index of nearest element
  24. //that is smaller than t
  25. int binarySearch(vector<Node> &a, int l, int u, int t)
  26. {
  27.      while(true)
  28.      {

  29.   int m = (l + u + 1) / 2;

  30.   if(a[m].end == t)

  31.        return m;

  32.   if(a[m].end < t)

  33.   {

  34.        //t is in (m + 1, u)

  35.        l = m + 1;

  36.        if (l > u)

  37.     assert(a.end < t);

  38.     return u;

  39.   }

  40.   if(a[m].end > t)

  41.   {

  42.        //t is in (l, m - 1)

  43.        u = m - 1;

  44.        if(l > u)

  45.     assert(a[l].end < t);

  46.     return l;

  47.   }
  48.      }
  49. }


  50. int maxSum(vector<Node> &a)
  51. {
  52.      //dummy node for coding convenience
  53.      Node dummyMin = {MIN, MIN, 0};
  54.      a.push_back(dummyMin);
  55.      sort(a.begin(), a.end(), compare);
  56.      int *dp = new int[a.size()];
  57.      dp[0] = 0;
  58.      for (int i = 1; i < a.size(); ++i)
  59.      {

  60.   //if i is not in the optimized solution

  61.   int v1 = dp[i - 1];

  62.   //if i is in the optimized solution

  63.   int k = binarySearch(a, 0, i - 1, a.start);

  64.   assert(k < i && k >= 0);

  65.   assert(a[k + 1].end > a.start && a[k].end <= a.start);

  66.   int v2 = dp[k] + a.value;

  67.   //find the max of two cases

  68.   dp = max(v1, v2);

  69.   assert(dp >= dp[i - 1]);
  70.      }
  71.      int r = dp[a.size() - 1];
  72.      delete[] dp;
  73.      return r;
  74. }
  75. #include <iostream>
  76. #include <algorithm>
  77. #include <vector>
  78. #include <limits>
  79. #include <assert.h>
  80. using namespace std;


  81. const int MIN = numeric_limits<int>::min();


  82. struct Node
  83. {
  84.      int start;
  85.      int end;
  86.      int value;
  87. };


  88. bool compare(const Node& a, const Node& b)
  89. {
  90.      return a.end < b.end;
  91. }


  92. int max(int a, int b)
  93. {
  94.      return a > b ? a : b;
  95. }




  96. //if t is not found in the array a
  97. //return the index of nearest element
  98. //that is smaller than t
  99. int binarySearch(vector<Node> &a, int l, int u, int t)
  100. {
  101.      while(true)
  102.      {

  103.   int m = (l + u + 1) / 2;

  104.   if(a[m].end == t)

  105.        return m;

  106.   if(a[m].end < t)

  107.   {

  108.        //t is in (m + 1, u)

  109.        l = m + 1;

  110.        if (l > u)

  111.     assert(a.end < t);

  112.     return u;

  113.   }

  114.   if(a[m].end > t)

  115.   {

  116.        //t is in (l, m - 1)

  117.        u = m - 1;

  118.        if(l > u)

  119.     assert(a[l].end < t);

  120.     return l;

  121.   }
  122.      }
  123. }


  124. int maxSum(vector<Node> &a)
  125. {
  126.      //dummy node for coding convenience
  127.      Node dummyMin = {MIN, MIN, 0};
  128.      a.push_back(dummyMin);
  129.      sort(a.begin(), a.end(), compare);
  130.      int *dp = new int[a.size()];
  131.      dp[0] = 0;
  132.      for (int i = 1; i < a.size(); ++i)
  133.      {

  134.   //if i is not in the optimized solution

  135.   int v1 = dp[i - 1];

  136.   //if i is in the optimized solution

  137.   int k = binarySearch(a, 0, i - 1, a.start);

  138.   assert(k < i && k >= 0);

  139.   assert(a[k + 1].end > a.start && a[k].end <= a.start);

  140.   int v2 = dp[k] + a.value;

  141.   //find the max of two cases

  142.   dp = max(v1, v2);

  143.   assert(dp >= dp[i - 1]);
  144.      }
  145.      int r = dp[a.size() - 1];

  146. int main(int argc, char *argv[])
  147. {
  148.      vector<Node> a = {{1, 3, 3}, {2, 3, 100}, {0, 4, 2}, {3,5, 7}, {2, 6,1}, {0, 6, 2}, {2, 6, 1}, {6, 7, 3}};
  149.      cout << maxSum(a) << endl;
  150.      return 0;
  151. }
复制代码

评分

参与人数 1大米 +100 收起 理由
wwwyhx + 100

查看全部评分

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册账号
隐私提醒:
  • ☑ 禁止发布广告,拉群,贴个人联系方式:找人请去🔗同学同事飞友,拉群请去🔗拉群结伴,广告请去🔗跳蚤市场,和 🔗租房广告|找室友
  • ☑ 论坛内容在发帖 30 分钟内可以编辑,过后则不能删帖。为防止被骚扰甚至人肉,不要公开留微信等联系方式,如有需求请以论坛私信方式发送。
  • ☑ 干货版块可免费使用 🔗超级匿名:面经(美国面经、中国面经、数科面经、PM面经),抖包袱(美国、中国)和录取汇报、定位选校版
  • ☑ 查阅全站 🔗各种匿名方法

本版积分规则

>
快速回复 返回顶部 返回列表