AcWing 165. 小猫爬山(dfs)
https://www.acwing.com/problem/content/167/
一共N只小猫,每个缆车最大承重量为W。N只小猫的重量分别是 C1、C2……CN。
当然,每辆缆车上的小猫的重量之和不能超过 W。
每租用一辆缆车,翰翰和达达就要付1美元,所以他们想知道,最少需要付多少美元才能把这N只小猫都运送下山?
数据范围 1≤N≤18,1≤Ci≤W≤108
输入样例:
5 1996
1
2
1994
12
29
输出样例:
2
详解见代码内部注释部分
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL,LL> PII;
const LL MAXN=1e18,MINN=-1e18;
const LL N=1e6+10,M=2023;
const LL mod=998244353;
const double PI=3.1415926535;
#define endl '\n'
LL n,m,a[N],che[N];
LL ans=18;
void dfs(LL idx,LL sum)
{
if(sum>=ans) return ;//max18只猫,max18辆车,多了无所谓
if(idx==n+1)
{
ans=sum;
return ;
}
for(int i=1;i<=sum;i++)//看看这只猫猫能不能和前面哪一辆车的猫猫们挤一挤
{
if(a[idx]+che[i]<=m)//挤得进去
{
che[i]+=a[idx];//挤一挤
dfs(idx+1,sum);//遍历下一只猫猫
che[i]-=a[idx];//突然发现这样搭配不好(占空间,出来挤一挤别的
}
}
//前面的都挤不进去
che[sum+1]=a[idx];//自己new一辆
dfs(idx+1,sum+1);//看看有没有别的猫猫伙伴来陪它
che[sum+1]=0;//突然发现这样搭配也不好,出来再重新挤一挤
}
int main()
{
cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);
int T=1;
//cin>>T;
while(T--)
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
sort(a+1,a+n+1);
reverse(a+1,a+n+1);
/*
for(int i=0;i<n;i++)
{
cout<<a[i]<<" ";
}
cout<<endl;
*/
dfs(1,1);//从第1只猫猫开始,车子一开始准备1辆,因为Ci<=m,所以一辆车最少都装得下一个
cout<<ans<<endl;
}
return 0;
}