Some immortal title

Pest Control

Topic Link
[Problem Description]
you need to spray insecticides on a infinitely long road.
On this road, running total of N points, wherein an i-th run at several points at coordinates pi axis. In each
one release point, you can choose left or right spray spray. However, due to the wind direction and the geographical environment, spraying left and
the right spraying effect is not necessarily the same. Specifically, a position to the left in the spray can cover [pi - li, pi] This section
area to the right to cover the spray can [pi, pi + ri] This section area.
Please you decide to spray each delivery point is to the left or right spray, to make the link length and the maximum covered by pesticides.
[Input]
The first line N.
Next N lines of pi, li, ri.
[Output]
output maximum length and is covered by the insecticide.

Input Output
4
1 2 2
3 3 3
4 3 3
6 2 2
Output
9

Sample shows
make the first and third spray delivery point to the left, the other right release point spray.
Such regions can be covered by [1,8], a total length of 9.
[DESCRIPTION] Data
for test points 1, 2, N≤ 15;
for the test points 3, 4, N≤ 3,000, ri = 0;
for test points 5, 6, N≤ 30;
For the test points 7, 8, N≤ 300;
for the test point 9, 10, N≤ 3,000;
guaranteed pi, li, ri ≤ 10 ^ 9.
Code

#include<bits/stdc++.h>
using namespace std;
const int N = 3010, inf = 1e9 + 7;
int n;
struct node {
    int p, l, r;
    bool operator < (const node &z) const {
        return p < z.p;
    }
} a[N];
int b[N * 3], tot, f[N][N * 3], id[N * 3];
int main() {
    //freopen("kill.in", "r", stdin);
    //freopen("kill.out", "w", stdout);
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        scanf("%d%d%d", &a[i].p, &a[i].l, &a[i].r);
        a[i].l = a[i].p - a[i].l; a[i].r = a[i].p + a[i].r;
        b[++tot] = a[i].p; b[++tot] = a[i].l; b[++tot] = a[i].r;
    }
    sort(b + 1, b + 1 + tot); tot = unique(b + 1, b + 1 + tot) - b - 1;
    sort(a + 1, a + 1 + n);
    for (int i = 1; i <= n; i++) {
        a[i].p = lower_bound(b + 1, b + 1 + tot, a[i].p) - b;
        a[i].l = lower_bound(b + 1, b + 1 + tot, a[i].l) - b;
        a[i].r = lower_bound(b + 1, b + 1 + tot, a[i].r) - b;
        id[a[i].p] = i;
    }
    //f[i][j]表示前i个区间,贡献最右点小于等于j
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= tot; j++) f[i][j] = f[i - 1][j];
        for (int j = a[i].l + 1; j <= a[i].p; j++) 
            f[i][j] = max(f[i][j], f[i][j - 1] + b[j] - b[j - 1]);
        //i区间贡献(k,j]
        int mx = f[i - 1][a[i].p];
        for (int j = a[i].p + 1; j <= a[i].r; j++) {
            f[i][j] = max(f[i][j], mx + b[j] - b[a[i].p]);
            //i区间贡献(a[i].p,j]
            if (id[j] && a[id[j]].l < a[i].p) mx = max(mx, f[i - 1][a[id[j]].l] + b[a[i].p] - b[a[id[j]].l]);
            //相交
        }
        for (int j = 2; j <= tot; j++) f[i][j] = max(f[i][j], f[i][j - 1]);
    }
    printf("%d\n", f[n][tot]);
    return 0;
} 

Guess you like

Origin www.cnblogs.com/zzy2005/p/11565225.html