这个题是在二分的题单上的,可是依据二分法写出来的会在oj上超时。依据题目以下给出的提示能够发现能通过贪心法每次都找最能满足的情况去填充每个包,这样就能保证使用的包的数量是最少的

二分法解法:

#include <iostream>
#include <stdio.h>
#include <cstring>
#include <algorithm>
#define MAX 100000

using namespace std;
int n,length;
int l[MAX];
bool cmp(int a,int b)
{
    return a<b;
}
bool judge(int mid)
{
    int r = 0,q = 0;
    int max = 0;
    int tag[n];//标记该物是否之前就打包过了
    memset(tag,0,sizeof(tag));
    for(int i = 0;i < n;i++){
        r = length - l[i];
        max = i;
        for(int j = n-1;j > i;j--){
            if((l[j] < r) &&!tag[j]){//尽量找到最能填满剩余空间的物
                max = j;
                break;
            }
        }
        if(!tag[max]){
            q++;
            tag[max] = 1;
        }
    }
    if(q < mid)
        return false;
    else
        return true;
}
int main()
{
    int high,low,mid,res;
    while(cin>>n){
    cin>>length;
    for(int i = 0;i < n;i++){
        cin>>l[i];
    }
    sort(l,l+n,cmp);
    high = n;
    low = 0;
    res = 0;
    while(low <= high){
        mid = (low+high)/2;
        if(judge(mid)){
            res = mid;
            low = mid+1;
        }
        else
            high = mid-1;
    }
    cout<<res<<endl;
    }
    return 0;
}


 

贪心法解法:

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
using namespace std;

int li[100003];
int ca[100003];

bool cmp(int a,int b)
{
    return a>b;
}
int main()
{
#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
#endif
    int n;
    int l;

    while(scanf("%d",&n)!=EOF)
    {
        scanf("%d",&l);
        for(int i=0;i<n;i++)
        {
            scanf("%d",&li[i]);
            ca[i] = l;
        }

        sort(li,li+n,cmp);

        int ans = 0;
        for(int i=0,j=n-1;i<=j;i++)
        {
            if(li[i] + li[j] <= l)
            {
                j--;
            }
            ans++;
        }
        printf("%d\n",ans);
    }
    return 0;
}


 

posted on 2017-06-14 19:21  yutingliuyl  阅读(113)  评论(0编辑  收藏  举报