I wrote this and then realized it was a very similar concept to what praveenik wrote. I haven't really looked too closely at the differences other than to note the idea of splitting and putting in priority queues that pivot the midpoint is a similar theme.

I don't know if this is the most efficient solution. popping and re-pushing the unused small priority queue elements seems like there might be an optimization there but I didn't put too much thought into it. I do believe it produces the correct answer.

Basically you have to match the largest of elements that is greater than the midpoint collection with the largest element that is smaller that the midpoint that the sum doesn't exceed the size limit. Call it pair. pop them off the queues and move on. If no element is found in the smaller than midpoint collection then it has to go solo onto a tape. Once the large queue is emptied then whatever is left in the small priority queue can just be paired up with anything else in the small queue in no particular order. So you just pop off the remaining elements in pairs and add one to the tape count for each pair.

```
// TestCase returns 11;
TapeCount tc;
vector<int> sizes = {52, 30, 30, 1, 1, 1, 49, 52, 48, 52, 49, 51, 51, 48, 48, 49, 70, 80, 80, 80, 80};
tc.getCount(sizes, 100);
class TapeCount{
public:
int getCount(vector<int> sizes, int maxSize)
{
priority_queue<int> pqLarge;
priority_queue<int> pqSmall;
int TCount = 0;
int midpoint = ceil(maxSize / 2);
for (auto s : sizes) {
if (s < midpoint)
{
pqSmall.push(s);
}
else {
pqLarge.push(s);
}
}
queue<int> lq;
while (!pqLarge.empty())
{
int lTop = pqLarge.top();
bool paired = false;
while (!pqSmall.empty() && !paired)
{
int sTop = pqSmall.top();
if (lTop + sTop <= maxSize)
{
paired = true;
pqSmall.pop();
pqLarge.pop();
TCount++;
}
else {
lq.push(sTop);
pqSmall.pop();
}
}
while (!lq.empty())
{
pqSmall.push(lq.front());
lq.pop();
}
if (!paired) {
TCount++;
pqLarge.pop();
}
}
while (!pqSmall.empty())
{
pqSmall.pop();
pqSmall.pop();
TCount++;
}
return TCount;
}
};
```