日常水题(贪心思想)
贪心思想:
在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,算法得到的是在某种意义上的局部最优解。
在许多时候还是非常好用的。
下面来两道程序设计竞赛的两道例题
1、北湖挖坑

看到这道题首先想到的就是贪心,去挖土,但是想要天数最少天数,
首先可以看出挖的坑和图形是相反的,所以直接将数组变成高度减去本身。
然后从左到右去找局部最优解即可。
比如a[0]=0,可得要挖的a[0]为h-a[0],也就是3,
然后初始化天数为a[0]从左到右遍历,如果右边比左边大,天数加上差值,最后结果就是答案
AC代码如下:
#include <stdio.h>
#include <stdlib.h>
int main() {
int n,h,i;
int a[100002];
scanf("%d",&n);
scanf("%d",&h);
for(i=0;i<n;i++){
scanf("%d",&a[i]);
a[i]=h-a[i];
}
long long ans=a[0];
for(i=1;i<n;i++){
if(a[i]>a[i-1]){
ans+=(a[i]-a[i-1]);
}
}
printf("%lld",ans);
}
2、北湖填坑

这道题和上道题类似,但是思想比较绕,
同样去找局部最优解,可以看出从左到右去遍历是行不通的,我们可以找出其中的最大值
因为终点方向有比自己大的才能保证能去填坑。
然后从两边向中间进行遍历,
初始化不用填坑,每次遇到比自己小的就让结果+1,最后就是答案
AC代码如下:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int t,n,i,j;
int a[102];
int index,max;
int main(){
scanf("%d",&t);
while(t--){
scanf("%d",&n);
int ans=0;
for(i=0;i<n;i++){
scanf("%d",&a[i]);
if(a[i]>max){
index=i;
max=a[i];
}
}
int ch=a[0];
for(i=1;i<index;i++){
if(a[i]<=ch){
ans+=ch-a[i];
}
else{
ch=a[i];
}
}
ch=a[n-1];
for(i=n-2;i>index;i--){
if(a[i]<=ch){
ans+=ch-a[i];
}
else{
ch=a[i];
}
}
printf("%d\n",ans);
}
}
浙公网安备 33010602011771号