CodeForces158B

来源:互联网 发布:安卓开发java基础 编辑:程序博客网 时间:2024/06/16 08:52

After the lessons n groups of schoolchildren went outside and decided to visit Polycarpus to celebrate his birthday. We know that the i-th group consists of si friends (1 ≤ si ≤ 4), and they want to go to Polycarpus together. They decided to get there by taxi. Each car can carry at most four passengers. What minimum number of cars will the children need if all members of each group should ride in the same taxi (but one taxi can take more than one group)?

Input

The first line contains integer n (1 ≤ n ≤ 105) — the number of groups of schoolchildren. The second line contains a sequence of integers s1, s2, …, sn (1 ≤ si ≤ 4). The integers are separated by a space, si is the number of children in the i-th group.

Output

Print the single number — the minimum number of taxis necessary to drive all children to Polycarpus.

Sample Input
Input

5
1 2 4 3 3

Output

4

Input

8
2 3 4 4 2 1 3 1

Output

5

题意比较的简单,有几组人要去坐车,但是有个条件,必须同组的人都坐在一辆车上,一辆车最多可以乘坐4人,问最少要叫几辆车。
如何减少车的数量?必须几组人坐一辆车!使得每一辆车的载人数尽可能的大。题目就变成了将各个数进行组合,和不得超过4,问多少组。
由于题目给的数据太过散乱,我们用sort排个序,比较好做点。很容易想到我们应该要将小数加到大数上,尽可能的凑到4。这里用到了贪心算法,一个数想要加到4,并且使要加的组数最大,那么尽可能的加一些小一点的数,是最好的。比如2要加到4,肯定2+1+1比2+2要好。整体就是这样。

#include <iostream>#include <algorithm>using namespace std;const int MAXN = 1e5+10;int num[MAXN];bool cmp(int a,int b){    return a<b;}int main(){    int n;    cin >>n;    for(int i=0;i<n;i++){        cin >>num[i];    }    sort(num,num+n,cmp);    for(int i=n-1,j=0;i>=0;i--){//两个循环变量,一个大数,一个小数        if(i==j){            break;        }        if(num[j]+num[i]<=4){            num[i]+=num[j];            num[j]=0;            j++;            i++;//num[i]将num[j]加上,但是不能确定是否第三组还能上,所以再来一次        }    }    int sum=n;    for(int i=n-1;i>=0;i--){        if(num[i]==0){/*剪枝,最能体现本算法的地方,i之前的全部为0了,例如num原                         本是2,3 eg:3都可以跟人一组,2当然可以跟人一组*/            sum=n-1-i;            break;        }    }    cout <<sum<<endl;    return 0;}
1 0
原创粉丝点击