贪心算法 独木舟 HZOJ

题面:

 

解题思路:

有两个点必须记住,一条船只能做两个人,且两个人重量相加不能超过最大负载量。

因此,第一步,我们先对n个人的体重进行从小到大排序,然后从第一个开始,如果第一个可以装的下且小于最大负载量,则向后搜寻小于等于剩下重量空余承重的最大值作为与第一个坐同一艘船的人。设置一个bool类型数组把n个未上船的人的值置为true(初始化为true),然后已经上船的就置为false。然后向后进行,循环结束所有人都上了船,用count记录船数。

代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>
#include <cmath>
#include <queue>
using namespace std;
int w,n;
int a[30005];
bool b[30005];
int Greedy(int a[],bool b[],int n,int w){
    sort(a,a+n);
    int cnt=0;
    for(int i=0;i<n;i++){
        if(a[i]<=w&&b[i]==true){
            int m=w-a[i];
            for(int j=i+1;j<n;j++){
                if(j==n-1&&a[j]<=m){//解决最大值是最后一个的情况 
                    b[j]=false;
                    break;
                }
                if(a[j]<=m&&a[j+1]>m){
                    b[j]=false;
                    break;
                }
            }
        cnt++;
        }
    }
    return cnt;
}
int main(){
    cin >> w >> n;
    for(int i=0;i<n;i++){
        cin >> a[i];
        b[i]=true;
    }
    cout << Greedy(a,b,n,w);
    return 0;
}

法二:

#include<bits/stdc++.h>
using namespace std;
int main(){

  int w,n,cnt=0,l=1,r,a[1001];//边界条件l=1,r=n
  scanf("%d%d",&w,&n);
  for(int i=1;i<=n;i++){
   scanf("%d",&a[i]);
  }
  sort(a+1,a+n+1);
  r=n;
  while(l<=r){
   if(a[l]+a[r]<=w){//如果两人体重小于船的载重cnt++
    cnt++;
    l++;//边界相应缩小
    r--;
   }else{
    cnt++;
    r--;
   }
  }
  printf("%d\n",cnt);

 return 0;
}

 

posted @ 2023-01-07 21:53  阿纳先森  阅读(83)  评论(0)    收藏  举报