日常水题(贪心思想)

贪心思想:

在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,算法得到的是在某种意义上的局部最优解。

在许多时候还是非常好用的。

下面来两道程序设计竞赛的两道例题

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);		
	}  
}

  

 

posted @ 2020-09-17 14:45  西凉锦马超  阅读(203)  评论(0编辑  收藏  举报