贪心模板

简单贪心问题

一船两人模型

一般的乘船模型是一定的体积,而只能乘坐2个人。
思路是先对数据进行排序,从小到大,然后从最小的开始,最小的和最大的相加,看看是否小于等于最大体积,不等的话最大值向前移,直到找到一个最大值和最小值的和满足条件
该最大值后面的数据就可以自己一个人乘船

有多组数据,每组数据由n+1行组成,第一行输入n,m,n为人数,m为船的最大载重,接下来n行为人的质量,每条川只能乘坐2人,求所需要船的最小值

模板1

我的思路,构建左边界,右边界,数据递增,进行查找,但十分麻烦
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int main(){
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF){
        int gr[100005];

        for(int i=0;i<n;i++){
            scanf("%d",&gr[i]);
        }
        sort(gr,gr+n);

        int sum=0;
        int left=0;
        int right=n-1;
        int lastright=n-1;
        while(left<right){
            while(gr[left]+gr[right]>m){
//当数据只剩下两个,且相加和大于4且第一个数据和两倍大于4时,会无故加一,所以要加上以下代码,表明筛选过头了
                if(right==left)break;
                right--;
            }

            sum++;

            sum+=lastright-right;//最小值-匹配到的最大值的后面的数据
            left++;
            right--;
            lastright=right;//及时更新上一个right

        }
        if(left==right){
            sum++;
        }

        //putchar('\n');
        printf("%d\n",sum);

    }
    return 0;
}

比较好的思路是:

模板2

多人乘坐模型

比较简单的模型思路时构建一个递减数组,因为对于下标i一定会增加,可以对最大值进行操作,但是如果时最小值在前,先去掉最大位,而最小值不能变,但i的值也会增加

//多人乘坐模型
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=1e5+5;
bool cmp(int a,int b){
    return a>b;
}
int main(){
    int n;
    while(scanf("%d",&n)!=EOF){
        int g[maxn];
        for(int i=0;i<n;i++){
            scanf("%d",&g[i]);
        }

        sort(g,g+n,cmp);

        int times=0;
        for(int i=0;i<n;i++){
            int sum=g[i]+g[n-1];
            if(sum<=4){
                n--;//最后一个数,即最小值不需要了,已经和最大值一起取坐车了
                times++;
                while(sum+g[n-1]<=4){//出现一辆车做多个人的情况
                    n--;//倒数第二个也不要了
                    sum+=g[n-1];
                }

            }else{
                times++;//取最大值单独坐车
            }

           // printf("%d %d\n",i,n-1);


        }
         printf("%d\n",times);
    }


    return 0;

}

转载于:https://www.cnblogs.com/Emcikem/p/11333815.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值