公园里有 n 个花园,初始时每个花园里都没有种花,园丁将花园从 1 到 n 编号并计划在编号为 i 的花园里恰好种 Ai 朵花,他每天会选择一个区间 [L,R](1≤L≤R≤N)并在编号为 L 到 R 的花园里各种一朵花,那么园丁至少要花多少天才能完成计划?
数据范围: ,
第一行包含一个整数 n 。
第二行包含 n 个空格隔开的数 ai 到 an。
输出完成计划所需的最少天数。
5 4 1 8 2 5
14
5 1 1 1 1 1
1
贪心法
public class Main { public static void main(String[] args) { java.util.Scanner sc = new java.util.Scanner(System.in); int N = sc.nextInt(); int[] target = new int[N]; for (int i = 0; i < N; ++i) { target[i] = sc.nextInt(); } int cnt = 0; for (int i = 1; i < N; ++i) { if (target[i - 1] > target[i]) { cnt += target[i - 1] - target[i]; } } System.out.println(cnt + target[N - 1]); } }
n = int(input()) arr = list(map(int, input().strip().split())) days = arr[-1] for i in range(n - 1): days += max(0, arr[i] - arr[i + 1]) print(days)
n = int(input()) arr = list(map(int, input().strip().split())) days = arr[0] for i in range(1, n): days += max(0, arr[i] - arr[i - 1]) print(days)
int main() { int N; cin >> N; int *p = new int[N + 1]; for(int i = 1; i <= N; i++) { cin >> p[i]; } int *dp = new int[N + 1]; dp[1] = p[1]; for(int i = 2; i <= N; i++) { if(p[i] <= p[i-1]) { dp[i] = dp[i-1]; } if(p[i] > p[i-1]) { dp[i] = dp[i-1] + p[i] - p[i-1]; } } cout << dp[N] << endl; delete []p; delete []dp; return 0; }
def solution(flowers): dp = [0]*len(flowers) dp[0] = flowers[0] # 初始化dp for i in range(1, len(flowers)): if flowers[i]<flowers[i-1]: dp[i] = dp[i-1] else: dp[i] = dp[i-1]+flowers[i]-flowers[i-1] return dp[-1] if __name__ == '__main__': n = int(input().strip()) flowers = list(map(int, input().strip().split())) print(solution(flowers))
def solution2(flowers): res = [] for i in range(len(flowers)-1): if flowers[i]>flowers[i+1]: res.append(flowers[i]-flowers[i+1]) res.append(flowers[-1]) return sum(res) if __name__ == '__main__': n = int(input().strip()) flowers = list(map(int, input().strip().split())) print(solution2(flowers))
思路一:递归
n = int(input()) l = list(map(int, input().split())) res = 0 L = [l] while len(L) > 0: next = [] for l in L: minN = min(l) tmp = [] res += minN for e in l: if e == minN: if len(tmp) != 0: next.append(tmp) tmp = [] else: tmp.append(e-minN) if len(tmp) > 0: next.append(tmp) L = next print(res)
但是上述解法只能A65%的数据
参考了大佬前排大佬的思路
思路二:贪心
因为相邻的差值是一定需要加到我们最后的结果中的,这里解释一下为什么加上最后一个数,是因为我们在循环中,没有计算最后的花朵的数量,而且最后一个园区的花朵,也必定要种l[-1]天
n = int(input()) l = list(map(int, input().split())) res = 0 for i in range(n-1): res += max(0, l[i] - l[i+1]) print(res + l[-1])
if __name__=='__main__': n = int(input()) num = list(map(int,input().split())) count = 0 for i in range(n-1): count += max(num[i]-num[i+1],0) print(count+num[-1])
n = int(input()) nums = list(map(int, input().split())) cnt = 0 for i in range(len(nums) - 1): cnt += max(0, nums[i] - nums[i + 1]) cnt += nums[-1] print(cnt)
#include<bits/stdc++.h> using namespace std; int main(void) { int n; cin>>n; vector<int> nums; vector<int> dp(n,0); int temp; for(int i = 0;i<n;i++) { cin>>temp; nums.push_back(temp); } dp[0] = nums[0]; for(int i=1;i<n;i++) { if(nums[i]<=nums[i-1]) dp[i] = dp[i-1]; else dp[i] = dp[i-1]+nums[i]-nums[i-1]; } cout<<dp[n-1]; }
def solve(n,nums): """ 单调栈 栈内只存储递增元素 时间复杂度O(n) :param n: :param nums: :return: """ nums.append(0) stack = [] res = 0 for i in range(n+1): if not stack or stack[-1]<=nums[i]: stack.append(nums[i]) else: res += stack[-1]-nums[i] while stack and stack[-1]>nums[i]: stack.pop() stack.append(nums[i]) print(res) n = int(input()) nums = [int(x) for x in input().split()] solve(n,nums)
import sys n = int(input().split()[0]) num = list(map(int,sys.stdin.readline().split())) # 单调栈,给以前的峰值进行浇花 stack = [] count = 0 for i in num: if len(stack) == 0: stack.append(i) continue elif stack[-1] <= i: stack.append(i) continue else: count += stack[-1] - i while(len(stack)!=0): if stack[-1] > i: stack.pop() else: break stack.append(i) if len(stack) !=0: count += stack[-1] print(count)
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; } }
import java.util.*; public class Main { public static void main(String args[]) { int n; // 动态规划 // dp[i] 表示种满当前花园需要的天数,p[i] 表示需要种的花的数量 // p[i] > p[i-1] dp[i] = dp[i-1] + p[i] - p[i-1] // p[i] <= p[i-1] dp[i] = dp[i-1] Scanner sc = new Scanner(System.in); n = sc.nextInt(); int[] p = new int[n]; int[] dp = new int[n]; for(int i = 0; i < n; i++) { int t = sc.nextInt(); p[i] = t; if(i == 0) dp[0] = p[0]; else dp[i] = p[i] <= p[i-1] ? dp[i-1] : dp[i-1] + p[i] - p[i-1]; } System.out.println(dp[n-1]); } }
import java.util.Scanner; import java.util.*; public class Main{ public static void main(String[] args) { Scanner de=new Scanner(System.in); while(de.hasNext()){ int n=de.nextInt(); int[] res=new int[n]; for(int i=0;i<n;i++){ res[i]=de.nextInt(); } Stack<Integer> stack=new Stack<>(); stack.push(res[0]); int count=0; for(int i=1;i<n;i++){ while(!stack.isEmpty()&&res[i]<stack.peek()){ int d=stack.pop(); int d1=res[i]; if(!stack.isEmpty()){ d1=Math.max(d1,stack.peek()); } count+=d-d1; } stack.push(res[i]); } while(!stack.isEmpty()){ int f=stack.pop(); if(!stack.isEmpty()){ count+=f-stack.peek(); }else{ count+=f; } } System.out.println(count); } } }
{ Scanner sc = new Scanner(System.in); int n=sc.nextInt(); int[] data=new int[n]; for(int i=0;i<n;i++) { data[i]=sc.nextInt(); } int res=0; for(int i=0;i<n-1;i++) { if(data[i]<data[i+1]) { res=res+(data[i+1]-data[i]); } } res+=data[0]; System.out.println(res); }
public static void main(String args[]) { Scanner sc = new Scanner(System.in); int n=sc.nextInt(); int[] data=new int[n]; for(int i=0;i<n;i++) { data[i]=sc.nextInt(); } int res = helper(data); System.out.println(res); } static int helper(int[] data) { if(data.length<=1) return data[0]; int min = Integer.MAX_VALUE; int cut=0; for(int i=0;i<data.length;i++) { if(data[i]<min) { min=data[i]; cut=i; } } for(int i=0;i<data.length;i++) { data[i]-=min; } int res=min; if(cut>0) { res+=helper(Arrays.copyOfRange(data,0,cut)); } if(cut<data.length-1) { res+=helper(Arrays.copyOfRange(data,cut+1,data.length)); } return res; }
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]); } }