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;
}
posted @ 2023-03-08 20:20  高尔赛凡尔娟  阅读(15)  评论(0编辑  收藏  举报