P5019-贪心&搜索
作者:互联网
P5019
春春是一名道路工程师,负责铺设一条长度为
n
的道路。铺设道路的主要工作是填平下陷的地表。整段道路可以看作是 n块首尾相连的区域,一开始,第
i
块区域下陷的深度为d_i
。春春每天可以选择一段连续区间
[L,R]
,填充这段区间中的每块区域,让其下陷深度减少1
。在选择区间时,需要保证,区间内的每块区域在填充前下陷深度均不为0
。春春希望你能帮他设计一种方案,可以在最短的时间内将整段道路的下陷深度都变为
0
。
- 输入格式
输入文件包含两行,第一行包含一个整数 n,表示道路的长度。 第二行包含 n个整数,相邻两数间用一个空格隔开,第
i
个整数为d_i
。
- 输出格式
输出文件仅包含一个整数,即最少需要多少天才能完成任务。
- 样例
6
4 3 2 5 3 5
- 输出样例
9
本题用两种方法解决:
贪心
-
显然,本题是要求我们找到填路最小的次数。题目是让找最小,为了简单,我们不妨朝找最大去想
-
首先,我们可以想到一种极端情况:
-
即,路上的坑都深为4,那么一共就只用填四次
4 4 4 4
-
当遇到最大的数时,无论怎样都得填上 最大的数 次
4 3 2 1 -> 4
-
所以我们不妨直接从第二个数一波遍历,如果该数比前一个大,大了几,就给总次数加几
for(int i = 2; i <= road; i++) ans += depth[i]-depth[i-1]
-
最后再加上之前没加的第一个数
ans += depth[1];
-
-
以下为总代码:
#include <bits/stdc++.h> using namespace std; int road; int depth[100000]; int cnt = 0; int main() { cin >> road; for(int i = 1; i <= road; i++) cin >> depth[i]; for(int i = 2; i <= road; i++) { if(depth[i] > depth[i-1]) cnt += depth[i]-depth[i-1]; } cout << cnt+depth[1]; return 0; }
搜索
-
题目本来说的就是在原来的区间中,找一个子区间,然后减去同样的数,因此我们不妨:
- 1.找一个区间
- 2.将此区间最小的数减成0
- 3.以此0为分界点,在0前的区间找最小,在0后的区间找最小
- 4.重复以上过程,直到子区间长度为0
-
以下为代码:
#include <bits/stdc++.h> using namespace std; int road,Min,mark; int depth[1000000]; int cnt = 0; void operate(int head,int tail) { Min = 0x7fffffff; for(int i = head; i <= tail; i++) { if(depth[i] < Min) { Min = depth[i]; mark = i; } } for(int i = head; i <= tail; i++) depth[i] -= Min; cnt += Min; } void search(int head,int tail) { if(tail < head) return; // operate(head,tail); search(mark+1,tail); search(head,mark-1); } int main() { cin >> road; for(int i = 1; i <= road; i++) cin >> depth[i]; search(1,road); cout << cnt; return 0; }
标签:道路,int,区间,depth,搜索,P5019,下陷,road,贪心 来源: https://www.cnblogs.com/sungoesdown/p/16135935.html