【题目来源】
https://www.acwing.com/problem/content/167/
【问题描述】
翰翰和达达饲养了 N 只小猫,这天,小猫们要去爬山。
经历了千辛万苦,小猫们终于爬上了山顶,但是疲倦的它们再也不想徒步走下山了(呜咕>_<)。翰翰和达达只好花钱让它们坐索道下山。
索道上的缆车最大承重量为 W,而 N 只小猫的重量分别是 C1、C2……CN。
当然,每辆缆车上的小猫的重量之和不能超过 W。
每租用一辆缆车,翰翰和达达就要付 1 美元,所以他们想知道,最少需要付多少美元才能把这 N 只小猫都运送下山?
【输入格式】
第 1 行:包含两个用空格隔开的整数,N 和 W。
第 2..N+1 行:每行一个整数,其中第 i+1 行的整数表示第 i 只小猫的重量 Ci。
【输出格式】
输出一个整数,表示最少需要多少美元,也就是最少需要多少辆缆车。
【数据范围】
1≤N≤18, 1≤Ci≤W≤10^8
【输入样例】
5 1996
1
2
1994
12
29
【输出样例】
2
【算法代码】
#include <bits/stdc++.h>
using namespace std;
const int maxn=20;
int n,w;
int maoW[maxn], cheW[maxn];
int ans;
//u:The current number of cats;
//v:The current number of cars
void dfs(int u, int v) {
if(v>=ans) return; //Optimized pruning
if(u==n) { //n cats have been searched
ans=v;
return;
}
for(int i=0; i<v; i++)
if(maoW[u]+cheW[i]<=w) { //Feasible pruning
cheW[i]+=maoW[u];
dfs(u+1,v);
cheW[i]-=maoW[u]; //Restore the scene
}
cheW[v]=maoW[u]; //Add a new car
dfs(u+1,v+1);
cheW[v]=0;
}
int main() {
cin>>n>>w;
for(int i=0; i<n; i++) cin>>maoW[i];
sort(maoW, maoW+n); //Sort from smallest to largest
reverse(maoW, maoW+n); //Sort from largest to smallest
ans=n;
dfs(0,0); //Start with the 0th cat and the 0th car
cout<<ans<<endl;
return 0;
}
/*
in:
5 1996
1
2
1994
12
29
out:
2
*/
【参考文献】
https://blog.youkuaiyun.com/weixin_44769957/article/details/108845693
https://blog.youkuaiyun.com/qq_42549254/article/details/90602609
https://www.acwing.com/video/478/
https://blog.youkuaiyun.com/qq_37867156/article/details/82534439
https://www.acwing.com/problem/content/167/