题目
思路
- 暴搜顺序:从前往后依次枚举每只小猫,枚举当前这只小猫应该放在哪一辆车上,递归完n层之后,就可以知道所有方案中的最少车辆总数
- 剪枝的情况:
- 优化搜索顺序:大部分情况下,应该优先搜索分支较少的节点
- 排除等效冗余
- 可行性剪枝
- 最优性剪枝
- 记忆化搜索(DP)
- 本题的剪枝:
- 优化搜索顺序:优先放重猫
- 可行性剪枝:如果放入当前的猫,车的重量超出,则舍弃该方案
- 最优性剪枝:如果当前车的数量已经大于等于ans(符合条件的最少车的数量)
代码
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=20;int n,m;
int w[N];
int sum[N]; //当前猫的重量
int ans=N;void dfs(int u,int k){ // u:当前猫的数量,k:当前车的数量//最优性剪枝if(k>=ans)return ; //当前车的数量大于等于ansif(u==n){ans=k;return;}//枚举当前这只猫可以放到哪辆车上去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);reverse(w,w+n);dfs(0,0);cout<<ans<<endl;return 0;
}