题解:
我的代码很简单,
步骤一:先用sort把纪念品的价格排序。
步骤二:然后从价格序列的两头同时开始,如果最高价格a[n-1]加上最低价格a[0]超过了给定的价格上限,那就试试a[n-2]和a[0]相加,从右到左直至有一个高价格的能和价格最低的分到一起。

价格太高不能和别的纪念品一起分组没关系,换它左边一个价格稍低的继续尝试;但价格低的如果能和价格高的一起分组,一定要赶紧分好,不然就保持不动让右边价格由高到低的不断尝试。

步骤三:假设a[0]和后面一个价格较高的a[x]分到了一起,那就试试a[1]和a[x-1]看看能不能分到一起,重复步骤二的过程。直到最后左边价格低的也慢慢变大,最后和右边价格高的任何一个都无法分组。

接下来就很容易理解了:左边价格低的,分了几组,就说明这次分组里面有两个纪念品在一起的组有几组,那么其他的都是单独分组
代码如下:

#include<bits/stdc++.h>
#include <algorithm>
using namespace std;
int main()
{
    int w, n, i, j;
    cin>>w>>n;
    int a[n];
    for(i = 0; i < n; i++)     cin>>a[i];
    sort(a, a+n);//将价格排序
    for(i = 0, j = n-1; i < j; )
    {
        if(a[i] + a[j] <= w)
        {
            i++;//价格低的能和价格高的一起分组,则左边向右进一位,右边向左进一位
            j--;
        }    
        else    j--;//若不能,左边不动,右边向左进一位继续尝试
    }
    cout<<(n-2*i + i)<<endl;
}