Atcoder beginner contest 336 -- D -- Pyramid

目录

D -- Pyramid:

题目大意:

思路解析:

代码实现:


D -- Pyramid:

题目大意:

给你一个长度为n的数组,你可以对这个数组进行以下操作。

操作1:选择任意一个元素,使其值大小减一。

操作2:删除第一个或者最后一个元素。

在进行有限次操作后,一定可以得到一个形如1 2 3 2 1这样的数字金字塔,问这个长度为n的数组能得到最长的数字金字塔的长度是多少。 1 2 3 2 1 这样的数字金字塔长度为3.

思路解析:

对于数字金字塔的前半部分,ak1 ak2 ak3 ak4 ... ak,如果他前面加上ak0就不能构成数字金字塔了,如果将ak认为是这个数字金字塔的中心,那么我应该知道ak向左最远能到哪个地方。

对于数字金字塔的后半部分 ak ak+1 ak+2....am 如果在后面加上am1就不能构成数字金字塔了,如果将ak认为是这个数字金字塔的中心,那么我应该知道ak向右最远能到哪个地方。

知道了ak的左右边界后,Math.min(l,r)就是ak的总体边界,即当ak为中心时,这个数字金字塔的最大长度,如果对于n个元素每个都能得到他们作为中心时数字金字塔的最大长度,那么对于这些最大长度整体求最大,那么这个长度就是答案。

代码实现:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
import java.util.*;

public class Main {

    public static void main(String[] args) throws IOException {
         Scanner input = new Scanner(System.in);
         int n = input.nextInt();
         int[] arr = new int[n];
         int[] l = new int[n];
         int[] r = new int[n];
        for (int i = 0; i < n; i++) {
            arr[i] = input.nextInt();
        }
        l[0] = 1;
        for (int i = 1; i < n; i++) {
            l[i] = Math.min(l[i - 1] + 1, arr[i]);
        }
        r[n - 1] = 1;
        for (int i = n - 2; i >= 0; i--) {
            r[i] = Math.min(r[i + 1] + 1, arr[i]);
        }
        int ans = 0;
        for (int i = 0; i < n; i++) {
            ans = Math.max(ans, Math.min(l[i], r[i]));
        }
        System.out.println(ans);
    }
}

你可能感兴趣的:(算法)