牛客网 2018校招真题 字节跳动 选区间

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_32767041/article/details/86440871

Description

牛客网 2018校招真题 选区间

Solving Ideas

n的范围[1,500000]太大,直接dp会超时

因为区间计算值都是由 区间最小值*区间和 得到的,所以在给定区间最小值的情况下,最优的情况一定是这个区间尽可能的扩展,直至区间的最小值不满足给定的最小值。
(扩展的过程因为满足 区间最小值 >= 给定区间最小值 的情况下,区间和一直增大,所以最终结果也增大)

又因为所有的数字都在[0, 100]的范围内,所以只需要遍历每一个数字为区间最小值的情况即可。

例如有序列[11, 12, 13, 1, 20, 21, 2, 30],设i表示给定的区间最小值,当i=10时,即规定 区间最小值 >= 10,

  • 满足区间的条件有[11, 12, 13], [20, 21], [30]
  • 对应的计算值为 11*(11+12+13), 20*(20+21), 30*30
  • 在给定i=10的情况下,最优值为max(11*(11+12+13), 20*(20+21), 30*30)

所以对i所有可能的情况都遍历一遍就能确定最终的最优值,i属于[0, 100]

Solution

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * n的范围[1,500000]太大,直接dp会超时
 *
 * 因为区间计算值都是由 区间最小值*区间和 得到的,
 * 所以在给定区间最小值的情况下,最优的情况一定是这个区间尽可能的扩展,
 * 直至区间的最小值不满足给定的最小值。
 * (扩展的过程因为满足 区间最小值 >= 给定区间最小值 的情况下,
 *      区间和一直增大,所以最终结果也增大)
 *
 * 又因为所有的数字都在[0, 100]的范围内,
 * 所以只需要遍历每一个数字为区间最小值的情况即可。
 *
 * 例如有序列[11, 12, 13, 1, 20, 21, 2, 30],设i表示给定的区间最小值
 * 当i=10时,即规定 区间最小值 >= 10,
 *     满足区间的条件有[11, 12, 13], [20, 21], [30]
 *     对应的计算值为 11*(11+12+13), 20*(20+21), 30*30
 *     在给定i=10的情况下,最优值为max(11*(11+12+13), 20*(20+21), 30*30)
 * 所以对i所有可能的情况都遍历一遍就能确定最终的最优值,i属于[0, 100]
 *
 * @author wylu
 */
public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str;
        while ((str = br.readLine()) != null) {
            int n = Integer.parseInt(str);
            int[] a = new int[n];
            String[] numStrs = br.readLine().split(" ");
            for (int i = 0; i < n; i++) {
                a[i] = Integer.parseInt(numStrs[i]);
            }

            long res = 0;
            for (int i = 0; i <= 100; i++) {
                int realMin = Integer.MAX_VALUE; //真正的区间最小值
                long sum = 0;
                boolean allBigger = true; //是否全部的a[j]都>=i
                for (int j = 0; j < n; j++) {
                    if (a[j] >= i) {
                        sum += a[j];
                        realMin = Math.min(realMin, a[j]);
                    }else {
                        allBigger = false;
                        res = Math.max(res, realMin * sum);
                        sum = 0;
                        realMin = Integer.MAX_VALUE;
                    }
                }
                if (allBigger) res = Math.max(res, realMin * sum);
            }
            System.out.println(res);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_32767041/article/details/86440871
今日推荐