题目传送门:https://codeforces.com/contest/1498/problem/B
题目大意:
给你一堆高度为1,长为2的幂的方块,再给你一个长度固定为w的盒子。问这个盒子的高度至少为多少才能把上面所有的方块都放进去?注意:你不能旋转方块!也就是说必须水平放置。
解题思路:
我们不用考虑方块的高度,因为都是1,只需要考虑长度能不能放下就行。首先把所有方块按照从大到小进行排序,然后开一个优先队列(默认从大到小排序),先将长度为w的空盒子放进去。然后从最大的开始比较,如果队首的值小于当前这个方块的长度(说明放不进去),就给这个队列插入一个新的节点,存放w-a【i】的值(给这个盒子直接加一层,把这个放进去,然后把剩余的空间存起来)。如果这个值大于等于当前方块长度(说明能放进去),就用这个值减去a【i】,然后存进去。最后队列的节点个数就是答案层数。
AC代码:
#include<bits/stdc++.h>
#define ll long long
#define maxn 1000005
using namespace std;
bool cmp(ll a,ll b)
{
return a>b;
}
int main()
{
int xxx=0;
ll t=0;
cin>>t;
while(t--)
{
static ll a[100005]={0};
ll n=0,w=0;
scanf("%lld%lld",&n,&w);
for(ll i=0;i<n;i++)
{
scanf("%lld",&a[i]);
}
sort(a,a+n,cmp);
priority_queue<int> q;
for(int i=0;i<n;i++)
{
if(q.empty())
{
q.push(w);
}
if(q.top()<a[i])
{
q.push(w-a[i]);
}
else
{
int now=q.top();
q.pop();
q.push(now-a[i]);
}
}
cout<<q.size()<<endl;
}
return 0;
}
优先队列
C++自带一种名字为优先队列的数据结构:priority_queue
定义方式为:priority_queue q,其用法和队列完全相同,但是会在队列中给节点进行排序,默认的情况是从大到小排序,即队列中的节点是按照降序排列的。如果想按照升序排列,可以写成
//升序排列
priority_queue <int,vector<int>,greater<int> > q;
//降序排列(默认)
priority_queue <int,vector<int>,less<int> >q;
如果存入的是字符串,则会按照字典序排序。