数据量很小,可以考虑暴搜,那我们考虑以怎样的顺序去搜索,假如每一趟用一个桶,那么就是最小需要几个桶的问题。我们可以考虑当前的衣服,1.可以放进已有的桶,2.在添加一个桶。如果不进行优化会超时的,对于第二种情况,每一个衣服都可以创建一个新桶,没有优化的余地了。对于第一种情况,我们知道搜索一般都是树形结构,如果扩展的结点越少,那么搜索的范围也就越小,显然,越大的衣服重量,后续的分枝就越小,毕竟越小的选择越大,那么分枝就越大,所以我们需要将衣服重量从大到小排序。还有一个常规的优化就是,如果当前的桶数已经大于等于目前的一个最优解,直接返回即可。

#include<iostream>
#include<bits/stdc++.h>
using namespace std;
const int maxn=30;
int a[maxn];
int sum[maxn];
int n,m;
int ans=maxn;
void dfs(int u,int k)//u当前遍历到第几只猫,k已经用了几个桶
{
    if(k>=ans)//如果目前用的桶已经超过当下的最优解,已经没有必要搜索下去了
        return;
    if(u==n)
    {
        ans=k;//不用是ans=min(ans,k),因为前面k>=ans,已经返回了
        return;
    }
    for(int i=0;i<k;i++)
    {
        if(a[u]+sum[i]<=m)//如果在第i个放下第u件衣服没有超过m,可以继续遍历下去
        {
            sum[i]+=a[u];
            dfs(u+1,k);
            sum[i]-=a[u];//回溯
        }
    }
    sum[k]=a[u];//新建一个桶
    dfs(u+1,k+1);
    sum[k]=0;//回溯
}
int main()
{
 cin>>n>>m;
 for(int i=0;i<n;i++)
    cin>>a[i];
 sort(a,a+n);
 reverse(a,a+n);//大到小排序
 dfs(0,0);
 cout<<ans<<endl;
    return 0;
}