翰翰和达达饲养了 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≤108输入样例:
5 1996 1 2 1994 12 29
输出样例:
2
对于这种问题肯定有限选择暴力枚举,那么我们在枚举前需要将其从大到小排列,以便于枝叶最小。
随后分析当前情况,无非就是加车or不加车(这里不加车就需要判断当前是否可以加小猫)。
于是我们先判断如果不加车的情况,不加车先利用for循环枚举小猫,然后判断小猫是否可以被装车,因为这里咱们要考虑车的问题,所以dfs参数就需要记录当前是第几只猫被装入以及当前共有多少辆缆车,随后利用数组cab记录每一辆的缆车所承载重量为了方便判断缆车是否都可以装入小猫,注意这里因为是枚举每一种情况,所以我们需要回溯一下。
然后我们就需要加车了,因为要加车的情况肯定是当前第x个小猫无法被装入,所以我们就要让x + 1并让缆车总数num+1。
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100;
int a[N],cab[N]; //a数组为小猫重量,cab数组记录对应的缆车目前占有的重量
int n,w;
int ans = 20;
void dfs(int x , int num)
{
if(num >= ans) return ;
if(x > n)
{
ans = min(ans , num);
return ;
}
for(int i = 1;i <= num;i++)
{
if(cab[i] + a[x] <= w)
{
cab[i] += a[x];
dfs(x + 1,num);
cab[i] -= a[x];
}
}
cab[num + 1] = a[x];
dfs(x + 1,num + 1);
cab[num + 1] = 0;
}
int main()
{
cin >> n >> w;
for(int i = 0;i < n;i++)
cin >> a[i];
sort(a , a + n);
reverse(a , a + n);
dfs(0,0);
cout << ans;
return 0;
}