Skip to content

14174: 【原4174】fuji

题目

题目描述

author: DS TA 原OJ链接:https://acm.sjtu.edu.cn/OnlineJudge-old/problem/4174

Description

“樱花开了几转,东京之旅一早比一世遥远。”

小L同学去富士山游玩,一天的游览结束之后,她准备回东京,然而路上有许许多多的高大的山峰,车辆无法通过。她获得了一种超能力,可以把一座山推倒。她想要推倒尽可能多的山峰,并且为了保证美观,她希望所有的山峰没有交点。可是她手边没有电脑,不知道要推倒多少山峰,现在请你来帮忙解决这个问题。

给出$n$座山峰的位置$x_i$和高度$h_i$,每推倒一座山峰会覆盖坐标轴上[$x_i-h_i,x_i$]或者[$x_i,x_i+h_i$]的区域,区域包括两个端点。没有推倒的山峰覆盖$x_i$一点。在覆盖区域没有交点的情况下,最多能推倒多少山峰?

Input Format

输入共三行,第一行包含一个正整数$n$,表示山峰的数目;

第二行包含$n$个正整数$x_i$,表示第$i$座山峰的位置;

第三行包含$n$个正整数$h_i$,表示第$i$座山峰的高度。

Output Format

输出共一行,包含一个整数,表示最多可推倒的山峰数目。

Sample Input

5 1 2 7 4 10 4 5 2 5 2

Sample Output

3

数据规模与约定

对于$70\%$的数据,$1\le n\le 20$;

对于$100\%$的数据,$1\le n \le 10^5$,$1\le x_i, h_i \le 10^{18}$,保证$x_i$两两不同。

ligongzzz's solution

#include "iostream"
#include "algorithm"
#include "cstdio"
#include "cstring"
using namespace std;

class mountain {
public:
    long long pos = 0;
    long long height = 0;
};

//山峰的位置
long long pos[100009] = { 0 };
long long height[100009] = { 0 };
mountain mountains[100009];

//保存DP数据
int dp_temp[100009][2];

//保存数量
int num = 0;

//动态规划
int dp(int cur_pos, int cur_state) {
    if (cur_pos >= num)
        return 0;
    if (dp_temp[cur_pos][cur_state] >= 0)
        return dp_temp[cur_pos][cur_state];
    //判断是否可以往左边推
    if (cur_pos == 0 || (cur_state == 0 && pos[cur_pos] - height[cur_pos] > pos[cur_pos - 1]) ||
        (cur_state == 1 && pos[cur_pos] - height[cur_pos] > pos[cur_pos - 1] + height[cur_pos - 1])) {
        int ans = 1 + dp(cur_pos + 1, 0);
        dp_temp[cur_pos][cur_state] = ans;
        return ans;
    }
    else {
        int ans = 0;
        //判断是否可以往右推
        if (cur_pos == num - 1 || pos[cur_pos] + height[cur_pos] < pos[cur_pos + 1]) {
            ans = 1 + dp(cur_pos + 1, 1);
        }
        //不推
        int shit_ans = dp(cur_pos + 1, 0);
        ans = shit_ans > ans ? shit_ans : ans;
        dp_temp[cur_pos][cur_state] = ans;
        return ans;
    }
}

int main() {
    scanf("%d", &num);

    memset(dp_temp, -1, sizeof(dp_temp));

    for (int i = 0; i < num; ++i)
        scanf("%lld", &mountains[i].pos);
    for (int i = 0; i < num; ++i)
        scanf("%lld", &mountains[i].height);

    //排序
    sort(mountains, mountains + num, [](mountain a, mountain b) {
        return a.pos < b.pos;
    });

    //写入
    for (int i = 0; i < num; ++i) {
        pos[i] = mountains[i].pos;
        height[i] = mountains[i].height;
    }

    printf("%d", dp(0, 0));

    return 0;
}

Neight99's solution

#include <iostream>

using namespace std;

const int maxN = 1e5 + 100;

struct M {
    long long pos;
    long long height;

    M() : pos(0), height(0) {}

    M(long long a, long long b) : pos(a), height(b) {}

    M operator=(M &right) {
        if (&right != this) {
            this->pos = right.pos;
            this->height = right.height;
        }

        return *this;
    }

    M(const M &right) {
        this->pos = right.pos;
        this->height = right.height;
    }
};

void qSort(M *nums, int l, int h) {
    if (l >= h) {
        return;
    }
    int first = l, last = h;
    M key(nums[first]);

    while (first < last) {
        while (first < last && nums[last].pos >= key.pos) {
            --last;
        }
        nums[first] = nums[last];
        while (first < last && nums[first].pos <= key.pos) {
            ++first;
        }
        nums[last] = nums[first];
    }
    nums[first] = key;
    qSort(nums, l, first - 1);
    qSort(nums, first + 1, h);
}

M mountain[maxN] = {};
int n, sum = 0;

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    cin >> n;
    for (int i = 1; i <= n; i++) {
        long long p;
        cin >> p;
        mountain[i].pos = p;
    }
    for (int i = 1; i <= n; i++) {
        long long h;
        cin >> h;
        mountain[i].height = h;
    }
    if (n == 1) {
        cout << 1;
        return 0;
    } else if (n == 2) {
        cout << 2;
        return 0;
    }

    qSort(mountain, 1, n);

    for (int i = 2; i < n; i++) {
        if (mountain[i].pos - mountain[i].height > mountain[i - 1].pos) {
            sum++;
        } else if (mountain[i].pos + mountain[i].height < mountain[i + 1].pos) {
            mountain[i].pos += mountain[i].height;
            sum++;
        }
    }
    sum += 2;

    cout << sum;

    return 0;
}