CodeForces 158B Taxi(代数算式解题)

本人ACM菜鸟一枚,偶然做到这(水)题,发现师兄和网上给代码大多都是用数组做的,本人是直接算的,都是贪心的思想。但就这题而言,个人认为直接用代数方法来算的代码效率更高,上题:

题目大意说,有n组人,每组1~4个人,他们要坐出租车去别的地方,每辆出租车最多坐四人。 题目限定同一组的人必须坐在同一辆车里。问最少需要几辆的士?

B. Taxi
time limit per test
3 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

After the lessons n groups of schoolchildren went outside and decided to visit Polycarpus to celebrate his birthday. We know that thei-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 integerss1, s2, ..., sn (1 ≤ si ≤ 4). The integers are separated by a space,si is the number of children in thei-th group.

Output

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

Examples
Input
5
1 2 4 3 3
Output
4
Input
8
2 3 4 4 2 1 3 1
Output
5
Note

In the first test we can sort the children into four cars like this:

  • the third group (consisting of four children),
  • the fourth group (consisting of three children),
  • the fifth group (consisting of three children),
  • the first and the second group (consisting of one and two children, correspondingly).

There are other ways to sort the groups into four cars.

贪心思想:

人数为4的组坐一辆车,人数为3的一组和人数为1的一组坐一辆车,人数为2的组两组一辆车。这样之后,2人组剩下1组或0组,而1人组和3人组只会剩下一种组(一开始组数多的那种组)或者1人组和3人组 组数相等刚好匹配完。

如果剩下的是3人组,那每组3人组坐一辆车(因为同组人员必须一辆车),加上是否有2人组剩下需要单独一辆车,就是答案。

如果剩下的是1人组,且2人组没剩,则1人组四人一辆车走,有余下的再加一辆。如果2人组剩一组,则看剩下的1人组是否大于2,不大于就和2人组一辆车走了。若剩下1人组组数大于2,则两个1人组和剩下的2人组一辆车。然后,就又是只剩下1人组的情况了。

如果一开始1人组和3人组就匹配完了,那么再看看2人组有没有剩余就可以出答案了

#include<iostream>
#include<string.h>
#include<algorithm>
#include<stdio.h>
#include<math.h>
using namespace std;
int n,a[100005];
long long sum,s1,s2,s3;

main()
{
	cin>>n;
	for(int i=1;i<=n;i++)
	{
	
		cin>>a[i];
		if(a[i]==1) s1++;//统计每组人数,4人组存在时答案直接+1 
		if(a[i]==2) s2++;
		if(a[i]==3) s3++;
		if(a[i]==4) sum++;
	}
	sum=sum+min(s1,s3)+s2/2;
	s2=s2%2;//2人组组数变更 ,非0即1 
	
	if(s3>s1)
	sum=sum+s2+s3-s1;//剩余的3人组每组单独一辆车,加上2人组 是否有余 
	else if(s1>s3)
	{
		s1=s1-s3; //1人组 组数变更 
		if(s2==0)
		{
			sum=sum+s1/4;
			if(s1%4!=0)
			sum=sum+1;
		}
		
		else
		{
			if(s1<=2)
				sum=sum+1;//余下的1人组小于2,和余下的2人组一辆车 
			else
			{
				sum=sum+1+(s1-2)/4;
				if((s1-2)%4!=0)
				sum=sum+1;
			}
			
		}
		
	}
	else  
	sum=sum+s2;//1人组和3人组人数相同,直接加上剩下二人组的一或零辆车  
	
	cout<<sum;
}

萌新欢迎各路大佬的指教~~

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值