贪心题,虽然是道水题,但是因为当时花了点时间,而且用了两种方法,并且尚存一些问题没有解决,所以写下来:
先讲贪心的做法:先将数据从大到小排序:将大的一边和小的一边相加,与4进行比较:如果小于等于4,队伍-2,车数+1,再与小的一边相加,如果仍满足条件,队伍-1,车数不变,重复过程,直到不满足条件;如果大于4,队伍-1,车数+1
先贴超时错误的代码:
#include<iostream>
#include<stdio.h>
#include<queue>
#include<functional>
using namespace std;
int main()
{
int n,ans=0;
scanf("%d", &n);
int a[10001];
for (int i = 0; i < n; ++i) {
scanf("%d", &a[i]);
}
sort(a, a + n,greater<int>());
for (int i = 0; i < n; ++i) {
while (a[i] + a[n-1] <= 4)
{
a[i] += a[n-1]; n--;
}
ans++;
}
printf("%d\n", ans);
return 0;
}
方法与正确方法思路差不多,但是超时原因尚不清楚
再贴正确代码:
#include<iostream>
#include<algorithm>
#include<functional>
using namespace std;
int a[100010];
int main()
{
int n;
cin>>n;
for(int i=0;i<n;i++) cin>>a[i];
sort(a,a+n,greater<int>());
int ans=0,sum=0;
for(int i=0;i<n;i++)
{
int sum=a[i]+a[n-1];
if(sum<=4)
{
ans++;
n--;
while(sum+a[n-1]<=4)
{
n--;
sum+=a[n-1];
}
}
else ans++;
}
cout<<ans<<endl;
return 0;
}
另一种方法则是纯粹的数学解法:
#include<iostream>
#include<stdio.h>
#include<queue>
#include<functional>
#include<cmath>
#include<stdlib.h>
using namespace std;
int main()
{
int n,ans=0,A=0,b=0,c=0;
scanf("%d", &n);
int a[100001];
for (int i = 0; i < n; ++i) {
scanf("%d", &a[i]);
if (a[i] == 4)ans++;
else if (a[i] == 3)c++;
else if (a[i] == 2)b++;
else if (a[i] == 1)A++;
}
if (c >= A) {
ans += c;
ans += (b+1) / 2;
}
else if (c < A) {
ans += b / 2;
b %= 2;
ans += c;
A -= c;
ans += A / 4;
A %= 4;
if (b) {
A -= 2;
ans++;
}
if (A > 0)ans++;
}
printf("%d\n", ans);
return 0;
}
原文地址:https://www.cnblogs.com/sqlbf/p/10317754.html