链接:
https://www.nowcoder.com/acm/contest/112/A
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
题目描述
现有n组人,m个地点,给出每组人的人数,每个地点可容纳的最大人数和选择的价格
要求一种方式,使得每组人都到一个各不相同的地点,最小化选择的价格
每个队伍的人都要在同一个地方每个地方只能有一个队伍
输入描述:
第一行n,m
第二行n个数,表示每组的人数
接下来m行,每行两个数,表示可容纳的最大人数和选择的价格
输出描述:
输出最小化选择的价格,无解输出-1
解题思路:这个题主要是小顶堆的应用,关于小顶堆的具体用法自己查一查,我就简单介绍一下小顶堆的作用,小顶堆就是堆顶元素始终维持堆里最小的那个值。所以这个题的解法就是对每组人数a[i]从m中找出所有满足可以装得下a[i]个人的地方,然后把这些地方的价格放入小顶堆里,然后对栈顶元素值取出来相加,就是所有的最省钱的方案了。还有对元素可以先从小到大排序,也可以从大到小排序,没要求的、(只是有个疑问是:两次弹出的堆顶元素难道没可能会是一样的吗,但是我这里并没有用标记数组来标记地方x有没有被选过,也是可以AC的)
AC代码:
#include
#include
#include
#include
#include
using namespace std;
int n, m;
const int maxn = 1e5 + 10;
int a[maxn];
long long int ans = 0;
struct Node
{
int people;
int price;
}p[maxn];
bool operator<(Node a, Node b) { return a.people > b.people || a.people == b.people&&a.price > b.price; } //小顶堆的具体用法
priority_queue,greater> Q; //定义一个小顶堆
bool cmp(int a, int b) //这个是我排序用的,其实也不需要,直接是sort()进行从小到大的排序也是可以的。
{
return a >= b;
}
bool cmp2(Node a,Node b)
{
if(a.people!=b.people) return a.people>b.people;
else return a.price>b.price;
}
int main()
{
cin >> n >> m;
for (int i = 0; i < n; i++)
{
cin >> a[i];
}
for (int i = 0; i < m; i++)
{
cin >> p[i].people >> p[i].price;
}
sort(p, p + m,cmp2);
sort(a, a + n,cmp);
for (int i = 0, j = 0; i= a[i])
{
Q.push(p[j].price);
j++;
}
if (Q.empty())
{
cout << "-1" << endl;
return 0;
}
ans+= Q.top();
Q.pop();
}
cout << ans << endl;
return 0;
}
B-车辆安排
链接:
https://www.nowcoder.com/acm/contest/112/B
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
题目描述
有n个队伍,每个队伍的人数小于等于5,每辆车最多坐5个人,要求一个队伍的人都在一辆车上,求最少的车数
输入描述:
第一行n
第二行n个数,表示每个队伍的人数
输出描述:
输出最少车数
解题思路:主要是用一个数组来存储队伍人数为1,2,3,4,5的个数,然后为了车辆安排的尽可能少,就需要每个车尽可能坐满人,所以就先考虑队伍人数为4的和为1的结合,然后队伍人数为3的与队伍人数为2的进行结合,接着再考虑剩下的队伍人数为2和1或者3和1结合,最后再单独考虑人数为1或2或3或是4的队伍安排。虽然这个代码看着晕,但是是最笨的那种。比较好理解。
AC代码:
#include
using namespace std;
int n;
const int maxn = 1e5 + 10;
int a[maxn];
int ans = 0;
bool f[maxn];
int cnt[6];
int main()
{
cin >> n;
ans = 0;
memset(cnt, 0, sizeof(cnt));
for (int i = 0; i < n; i++)
{
cin >> a[i];
cnt[a[i]]++;
}
ans += cnt[5];
if (cnt[1] >= cnt[4])
{
ans += cnt[4];
cnt[1] = cnt[1] - cnt[4];
cnt[4] = 0;
//cout << "1" << " " << ans << endl;
}
if (cnt[1] < cnt[4])
{
ans += cnt[4];
cnt[1] = 0;
//cout << "2" << " " << ans << endl;
}
if (cnt[2] >= cnt[3])
{
ans += cnt[3];
cnt[2] = cnt[2] - cnt[3];
cnt[3] = 0;
//cout << "3" << " " << ans << endl;
}
if (cnt[2] < cnt[3])
{
ans += cnt[2];
cnt[3] = cnt[3] - cnt[2];
cnt[2] = 0;
//cout << "4" << " " << ans << endl;
}
if (cnt[3] > 0 && cnt[1] == 0)
{
ans += cnt[3];
cnt[3] = 0;
//cout << "5" << " " << ans << endl;
}
if (cnt[2] > 0 && cnt[1] == 0)
{
if (cnt[2] % 2 == 0) ans += cnt[2] / 2;
else ans += cnt[2] / 2 + 1;
cnt[2] = 0;
//cout << "6" << " " << ans << endl;
}
if (cnt[2] > 0 && cnt[1] > 0)
{
if (cnt[2] % 2 == 0)
{
ans += cnt[2] / 2;
cnt[1] = cnt[1] - cnt[2] / 2;
}
else
{
ans += cnt[2] / 2 + 1;
cnt[1] = cnt[1] - cnt[2] / 2 - 3;
}
if (cnt[1] > 0)
{
if (cnt[1] % 5 == 0) ans += cnt[1] / 5;
else ans += cnt[1] / 5 + 1;
}
//cout << "7" << " " << ans << endl;
cnt[2] = 0;
cnt[1] = 0;
}
if (cnt[3] > 0 && cnt[1] > 0)
{
ans += cnt[3];
//cout << "8" << " " << ans << endl;
cnt[1] = cnt[1] - 2*cnt[3];
if (cnt[1] > 0)
{
if (cnt[1] % 5 == 0) ans += cnt[1] / 5;
else ans += cnt[1] / 5 + 1;
//cout << "8" << " " << ans << endl;
}
//cout << "8" << " " << ans << endl;
cnt[3] = 0;
cnt[1] = 0;
}
cout << ans << endl;
return 0;
}