#include using namespace std; const int N = 20; int n, m; int w[N]; int sum[N]; int ans = N; void dfs(int u, int len) { // 最优性剪枝 if (len >= ans) return; if (u == n + 1) { // 走完 ans = len; // 更新答案 return; } for (int i = 0; i < len; i++) if (sum[i] + w[u] <= m) { // 能放下的情况 sum[i] += w[u]; // 放一下试试 dfs(u + 1, len); // 下一只小猫,缆车没有增加 sum[i] -= w[u]; // 回溯 } // 新开一辆车 sum[len] += w[u]; dfs(u + 1, len + 1); sum[len] -= w[u]; // 恢复现场 } int main() { cin >> n >> m; for (int i = 1; i <= n; i++) cin >> w[i]; // 优化搜索顺序 21ms //  不加优化搜索顺序 88ms // Q:为什么可以采用这样的优化策略? // A: dfs搜索的顺序很关键,很玄学,本着有矛盾先暴露,将一些分枝尽早结束,提前返回,可以提高搜索效率  sort(w + 1, w + 1 + n, greater()); dfs(1, 0); cout << ans << endl; return 0; }