dfs的一般优化(5种)
1优化搜索顺序
——大部分情况下,我们应该优先搜索分支较少的节点。在本题中,我们可以先从大到小排序。因为我们先选择大的,后面的选择就会减少,分支也会减少。相反,如果先搜索小的,后面的选择多,搜索的分支会变多。
2排除等效冗余
——本题我们搜索时是枚举每一个宝可梦应该放到哪个球里,已经没有重复搜索了。但如果枚举每一个球应该放哪些宝可梦则会增加搜索次数。
3可行性剪枝
——加上枚举到的宝可梦超过m时,则直接剪枝。
4最优化剪枝
——当k>=ans时,说明此时的方案继续搜素下去也不能再优化答案了,直接return。
5优化搜索顺序
——本题没有用到。
#include <bits/stdc++.h>
using namespace std;
int n, m;
int w[30];
int sum[30];
int ans = 20;//最多只有20组
int cmp(int a, int b)
{
return a > b;
}
void dfs(int u, int k)
{
//最优性剪枝
if (k >= ans)
return;
if (u == n)
ans = k;
for (int i = 0; i < k; i++)
if (sum[i] + w[u] <= m)//可行性剪枝
{
sum[i] += w[u];
dfs(u + 1, k);
sum[i] -= w[u];//恢复现场
}
//新加一个沉重球
sum[k] = w[u];
dfs(u + 1, k + 1);
sum[k] = 0;//恢复现场
}
int main()
{
cin >> n >> m;
for (int i = 0; i < n; i++)
cin >> w[i];
//优化搜索顺序
sort(w, w + n, cmp);
dfs(0, 0);
cout << ans << '\n';
}