传送门
题意
运送(n)个猫下山,每个车上最多承受(w)重量,(n)只小猫的重量分别为(c_{1},c_{2},dots ,c_{n})。
每用一辆车需要(1)元,求最少可以花多少钱将所有猫送下山
数据范围
(1leq N leq 18)
(1leq C_{i}leq Wleq 10^{8})
题解
(n)范围较小,可以直接暴搜,
两个状态,(u)记录当前是第几只猫,(cnt)表示当前装了几辆车
搜索时要搜索以每个猫单独在一辆车里面的情况,然后一次将其它猫装入当前车
两个剪枝优化。
- 如果当前的车的数目已经大于已经得到数目最小值可以终止
- 搜索车的重量的时候,先将重量重的放入可以减少搜索树分支的数量
Code
#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for(int i=a;i<n;i++)
const int N=20;
int car[N],c[N];
int n,w;
int ans;
void dfs(int u,int cnt)
{
if(cnt >= ans) return;
if(u==n+1)
{
ans=min(ans,cnt);
return;
}
rep(i,1,cnt+1)
{
if(car[i]+c[u]<=w)
{
car[i]+=c[u];
dfs(u+1,cnt);
car[i]-=c[u];
}
}
car[cnt+1]=c[u];
dfs(u+1,cnt+1);
car[cnt+1]=0;
}
int main()
{
cin>>n>>w;
rep(i,1,n+1) cin>>c[i];
sort(c+1,c+1+n);
reverse(c+1,c+1+n);
ans=n;
dfs(1,0);
cout<<ans<<endl;
}