互不重叠线段的最大价值

255 阅读1分钟

在坐标的x轴上有n条线段,第i条选段拥有 wi 的价值。请问选出若干条互不重叠的线段的最大价值是多少。 输入描述: 第一行一个整数n,代表线段的条数 第二行n个整数,代表每条线段中点的横坐标 第三行n个整数,代表每条线段的半径长度(即整条线段长度的一般) 第四行n个整数,代表每条线段的价值

输入17
3 4 6 8 3 2 6
4 2 5 6 1 4 6
输出113

解题思路:动态规划;对线段的中点进行排序,从做往右取计算dp[i] dp[i]为第i条线段作为最后一个线段的最大价值。再O(n)地考虑他在第i条线段前面的线段的dp值,然后进行转移。

class Node {
  constructor(p, r, w) {
    this.p = p;
    this.r = r;
    this.w = w;
  }
}

// pArr为坐标中点 rArr为半径 wArr为价值
const main = (len, pArr, rArr, wArr) => {
  const dp = new Array(len);
  const a = new Array(len);

  for (let i = 0; i < len; i++) {
    a[i] = new Node(pArr[i], rArr[i], wArr[i]);
  }

  // 由小到大排序
  a.sort((j, k) => j.p - k.p);

  for (let i = 0; i < len; i++) {
    dp[i] = a[i].w;
  }

  let ans = 0;

  for (let i = 0; i < len; i++) {
    for (let j = 0; j < i; j++) {
      // 不相交
      if (a[i].p - a[i].r >= a[j].p + a[j].r) {
        dp[i] = Math.max(a[i].w + dp[j], dp[i]);
      }
    }
    ans = Math.max(ans, dp[i]);
  }
  return ans;
};

main(7, 
    [3, 4, 6, 8, 3, 2, 6], 
    [2, 3, 2, 1, 3, 2, 2], 
    [2, 5, 2, 5, 7, 8, 3]
); // 13