贪心问题(贪心、标记)

版权声明:侵删 [email protected] https://blog.csdn.net/weixin_43350051/article/details/84781508

新手 贪心算法:

                                                                                                             点击查看试题原题

 

                                                 问题 B: 【贪心】种树

                                                              时间限制: 1 Sec  内存限制: 128 MB
                                                                         提交: 117  解决: 55
                                                             [提交] [状态] [讨论版] [命题人:admin]

题目描述

 一条街的一边有几座房子。因为环保原因居民想要在路边种些树。路边的地区被分割成块,并被编号成1..N。每个部分为一个单位尺寸大小并最多可种一棵树。每个居民想在门前种些树并指定了三个号码B,E,T。这三个数表示该居民想在B和E之间最少种T棵树。当然,B≤E,居民必须记住在指定区不能种多于区域地块数的树,所以T≤E-B+l。居民们想种树的各自区域可以交叉。你的任务是求出能满足所有要求的最少的树的数量。

写一个程序计算最少要种树的数量。

输入

第一行包含数据N,区域的个数(0<N≤30000);
第二行包含H,房子的数目(0<H≤5000);
下面的H行描述居民们的需要:B E T,0<B≤E≤30000,T≤E-B+1。

输出

树的数目。

样例输入

复制样例数据

扫描二维码关注公众号,回复: 5393887 查看本文章
9
4
1 4 2
4 6 2
8 9 2
3 5 2

样例输出

5

嗯   看到下面挺开心的 :

源代码:

#include<stdio.h>
int main()
{
    long long int a[30006][6],flag[5006]={0},n,max,i,j,temp,count,count1;
    scanf("%lld%lld",&max,&n);
    for(i=0;i<n;i++){
        for(j=0;j<3;j++){
            scanf("%lld",&a[i][j]);
        }
    }
    for(i=0;i<n-1;i++){
        for(j=0;j<n-i-1;j++){
            if(a[j][1]>a[j+1][1]){
                temp=a[j][1];
                a[j][1]=a[j+1][1];
                a[j+1][1]=temp;

                temp=a[j][0];
                a[j][0]=a[j+1][0];
                a[j+1][0]=temp;

                temp=a[j][2];
                a[j][2]=a[j+1][2];
                a[j+1][2]=temp;
            }
        }
    }
    for(i=0;i<n;i++){
        count=0;
        for(j=a[i][0];j<=a[i][1];j++){
            if(flag[j]==1){
                count++;
            }
        }
        if(a[i][2]>count){
            a[i][2]-=count;
        }
        else{
            a[i][2]=0;
        }
 //       printf(" #%lld %lld#",a[i][1],a[i][2]);
        for(j=a[i][1];j>(a[i][1]-a[i][2]);j--){
 //               printf(" *%lld* ",j);
                flag[j]=1;
        }
    }
    count1=0;
    for(i=1;i<=max;i++){
        if(flag[i]==1){
            count1++;
        }
    }
    printf("%lld\n",count1);
    return 0;
}

题解(个人意见):

1.先对输入的每组数据按结尾位置排序,之前接触过冒泡排序一维数据和二维两个数据排序,第一次接触三个数据同位置排序(开始在一个数组中排序后也在同一个数组中),不过也可以理解。

2.用标记的放法把种过树的地方标记一下。

3.在查找每组数据的时候都要先循环查看在这个范围内的位置已经种了几棵树,如果种的数目已经超过本组数据要种的数目,将存储本组数据的a[i][2]变为零,不然就在a[i][2]的基础上减去已经种上树的数量。

4.如果a[i][2]的值不是0,就在这组数据的最后往前循环种树(标记)。

5.用for循环从0循环到max(区域最大值),查找标记的数目就是最小的数目。

最后吐槽 今天调这个代码调了有两个小时,最后发现我把一个if放在了for循环里面(爽!!!)。

 

猜你喜欢

转载自blog.csdn.net/weixin_43350051/article/details/84781508