首页 > 试题广场 >

种花

[编程题]种花
  • 热度指数:3173 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 64M,其他语言128M
  • 算法知识视频讲解
公园里有 n 个花园,初始时每个花园里都没有种花,园丁将花园从 到 n 编号并计划在编号为 的花园里恰好种 A朵花,他每天会选择一个区间 [LR]1≤L≤R≤N)并在编号为 到 的花园里各种一朵花,那么园丁至少要花多少天才能完成计划?

数据范围:

输入描述:
第一行包含一个整数 n 。

第二行包含 n 个空格隔开的数 ai 到 an


输出描述:
输出完成计划所需的最少天数。
示例1

输入

5
4 1 8 2 5

输出

14
示例2

输入

5
1 1 1 1 1

输出

1
分片暴力
import java.util.*;

public class Main {

    public static void main(String[] args) {

        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int[] ns = new int[n];
        for (int i = 0; i < n; i++) {
            ns[i] = in.nextInt();
        }
        int ans = 0;
        // 找到第一个大于0的数
        int left = findLeft(ns, 0);
        while (left != -1) {
            // 从left开始,更新ns数组
            ans += func(ns, left);
            // 找到第一个大于0的数
            left = findLeft(ns, left);
        }
        System.out.println(ans);
    }

    private static int func(int[] ns, int left) {
        int min = ns[left];
        int right = ns.length;
        // 第一次循环,维护min值和right
        for (int i = left + 1; i < ns.length; i++) {
            if (ns[i] == 0) {
                right = i;
                break;
            }
            if (ns[i] < min) {
                min = ns[i];
            }
        }
        // 第二次循环,更新ns数组
        for (int i = left; i < right; i++) {
            ns[i] -= min;
        }
        return min;
    }

    private static int findLeft(int[] ns, int pst) {
        // 找到left,即第一个大于0的数,若没有则返回-1
        for (int i = pst; i < ns.length; i++) {
            if (ns[i] > 0) {
                return i;
            }
        }
        return -1;
    }

}


发表于 2022-08-12 17:00:31 回复(0)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * @Author: coderjjp
 * @Date: 2020-05-11 12:40
 * @Description: 种花
 * @version: 1.0
 */
public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int N = Integer.parseInt(br.readLine());
        String[] line2 = br.readLine().split(" ");
        int A[] = new int[N];
        for (int i = 0; i < N; i++)
            A[i] = Integer.parseInt(line2[i]);
        int cur = 0;
        int ans = 0;
        while (cur < N && A[cur] == 0)//找到第一个不为0
                cur++;
        while (cur < N){
                        //但下面这个循环耗时比较长
            for (int j = cur; j < N && A[j] > 0; j++)//从cur开始向后种,能种的全种上
                A[j]--;
            ans++;//天数加1
            while (cur < N && A[cur] == 0)//种完一遍后从cur向后找到下一个不为0的待种花园
                cur++;
        }//cur = N, 说明已全部种上,跳出循环,贪心法
        System.out.println(ans);
    }
}
参考网友的代码,动态规划实现,效率确实相当高。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * @Author: coderjjp
 * @Date: 2020-05-11 13:42
 * @Description:
 * @version: 1.0
 */
public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int N = Integer.parseInt(br.readLine());
        String[] line2 = br.readLine().split(" ");
        int A[] = new int[N];
        for (int i = 0; i < N; i++)
            A[i] = Integer.parseInt(line2[i]);
        int dp[] = new int[N];
        dp[0] = A[0];
        for (int i = 1; i < N; i++){
            if (A[i] <= A[i-1])
                dp[i] = dp[i-1];
            else
                dp[i] = dp[i-1] + (A[i] - A[i-1]);
        }
        System.out.println(dp[N-1]);
    }
}


编辑于 2020-05-11 13:54:54 回复(0)