贪心思想:
在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,算法得到的是在某种意义上的局部最优解。
在许多时候还是非常好用的。
下面来两道程序设计竞赛的两道例题
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 ",ans); } }