165. 小猫爬山(dfs,剪枝)

https://www.acwing.com/problem/content/167/

一般dfs,虽然是一般dfs但也不是一下子就能秒的
首先还得是确定搜索顺序
这里是:从前往后,依次枚举每一只小猫,对于每一只小猫,枚举这只小猫可以坐的车,以及再开一辆新车
这样的顺序可以覆盖每种情况
剪枝:
优化搜索顺序:排序之后,从最重的猫开始枚举,尽量的减少分支的产生
最优剪枝:如果此时搜索的答案没有之前的好,不管有没有搜索完毕,直接return
可行剪枝:如果放上这个猫后会超重,就放弃,直接不产生分支

#include<iostream>
#include<algorithm>

using namespace std;

const int N = 20;

int c[N],w,n;
int res = N;
int sum[N];

void dfs(int step,int k) // 第step只猫,k为车数量
{
    if(k >= res) return;//最优性剪枝
    if(step == n)
    {
        res=k;//搜索完毕,更新答案
        return;
    }
    //枚举当前猫放到哪辆车上
    for(int i=0;i<k;i++)
        if(sum[i]+c[step]<=w)//可行性剪枝
        {
            sum[i]+=c[step];
            dfs(step+1,k);
            sum[i]-=c[step];
        }
    
    //新开一辆车
    sum[k]+=c[step];
    dfs(step+1,k+1);
    sum[k]=0;
}

int main()
{
    cin >> n >> w;
    for(int i=0;i<n;i++)cin >> c[i];
    sort(c,c+n);
    reverse(c,c+n);
    dfs(0,0);
    cout << res << endl;
    return 0;
}

 

posted @ 2023-03-13 13:40  风乐  阅读(25)  评论(0)    收藏  举报