【发布时间】:2020-10-17 09:22:25
【问题描述】:
给定一个位于 x 轴上的城市。它有 n 个建筑物。第一座建筑位于 x = 1 处,高度为 h1,第二座建筑位于 x = 2 处,高度为 h2,依此类推。你是一个拿着剑想要摧毁城市的巨大怪物。你本质上也是一名计算机科学家,所以你的效率是关键,因此你想用最少的动作摧毁这座城市。
你可以做两个动作之一:
1.从 x = L 到 x = R 进行水平切割,将建筑物的高度从 x = L 到 X = R 减少 1。
2。在 x = P 处进行垂直切割,在 x = P 处完全摧毁建筑物,从而使其高度为零。**
注意:对于第一种类型的移动,从 L 到 R 范围内的每个城市必须至少有 1 个高度剩余,即您不能穿过空白区域。
打印摧毁城市所需的最少移动次数。
输入
第一行包含测试用例的数量。 对于每个测试用例,第一行包含建筑物的数量 n。 第二行包含 n 个整数,表示建筑物的高度
输出
对于每个测试用例,在新行上打印摧毁城市的最少移动次数。
注意事项
1 ≤ n ≤ 1000 0 ≤ hi ≤ 1000
示例输入 0
2
5
2 2 2 3 3
5
10 2 10 2 10
样本输出 0
3
5
我无法弄清楚这个问题的方法。 我的代码不适用于以下输入: 1 1 1 2 4 5 7 7 8 9** 在我的代码中,我减少了所有元素的最小值。然后找出零之间的子数组,然后将子数组(j-i)的长度与最小值进行比较。如果长度更小,那么我们需要跟随移动 2,否则移动 1。 我的代码:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.Scanner;
public class Main {
static int findmin(int arr[], int i, int j) {
int min = Integer.MAX_VALUE;
for (int k = i; k < j; k++) {
if (min > arr[k]) {
min = arr[k];
}
}
return min;
}
static void subtractmin(int arr[], int i, int j, int min) {
//if both the length of subarray and min are equal, we destroy separately
if (j - i <= min) {
for (int k = i; k < j; k++) {
// if
arr[k] = 0;
}
} else {
//subtract all
for (int k = i; k < j; k++)
// if
{
arr[k] -= min;
}
}
}
public static void main(String[] args) {
//int input[] = {10, 2, 10, 2, 10};// 5
//int input[] = {2, 2, 2, 3, 3};// 5
Scanner sc = new Scanner(System.in);
int t = sc.nextInt();
while (t-- != 0) {
int zeros = 0;
int n = sc.nextInt();
int input[] = new int[n];
int min = Integer.MAX_VALUE;
for (int i = 0; i < n; i++) {
input[i] = sc.nextInt();
if (min > input[i]) {
min = input[i];
}
if (input[i] == 0) {
zeros++;
}
}
//subtract minimum element from array
int count = 0;
if (zeros == 0) {
count += min;
subtractmin(input, 0, n, min);
} else {
count += min;
subtractmin(input, 0, n, min);
}
//traverse the array and findsubarrays between 0's
//1) if an element is surrounded by 0's it will be destroyed at once separately
// 2) also if length of subarray<min element, they all need to be destroyed separately
// 3) if min<length of subarray they need to be destroyed at once with count+=min
int i = 0, j = 0;
while (true) {
//move i to the first non zero element
for ( i = 0; i < n; i++) {
if (input[i] != 0) {
break;
}
}
//means whole array is 0;
if (i == n) {
System.out.println(Math.min(count, n - zeros));
break;
}
///start with the first non zero element and fin
for (j = i; j <= n; j++) {
if ( j == n || input[j] == 0) {
// take out min element
int minEle = findmin(input, i, j) ;
//if min lement is greater than subarray size, destroy separately
count += Math.min(minEle, j - i);
//System.out.println("count="+count+"min element="+minEle);
// subtract minimum element
subtractmin(input, i, j, minEle);
}
//if last elemnt is not zero
}
}
}
}
}
【问题讨论】:
-
这与 java 或 python 有什么关系? :)
-
嘿!请发布您的代码。
-
我已经发布了我的代码。
-
您提到您的代码不适用于此输入。输出是什么,预期输出是什么?
-
我的输出是 9。预期的输出是 8..
标签: java algorithm data-structures dynamic-programming divide-and-conquer