《算法竞赛进阶指南》0x22dfs 小猫爬山

题目链接:https://www.acwing.com/problem/content/167/

首先看到这个数据范围就知道需要用搜索来实现,保存的当前状态是一共用了多少缆车,当前扫描的小猫编号 ,每个缆车中的重量。其中第三个状态是可以用全局数组来维护的,

前面两个状态作为dfs的参数传入,每次可以产生cnt+1个分支,cnt为缆车数量。优先排重量比较大的,因为在搜索树的深处大的重量更难搜索到最优状态,搜索树的规模将会变得

十分庞大。

代码如下:

#include<iostream>
#include<algorithm>
using namespace std;
#define maxn 25
int cab[maxn],w[maxn];
int n,weight;
int ans=0x7f;
void dfs(int now,int cnt){
    if(cnt>=ans)return ;//不会比最终结果更优,剪枝
    if(now==n){
        ans=min(ans,cnt);
        return ;
    }
    for(int i=0;i<cnt;i++){
        if(cab[i]+w[now]<=weight){
            cab[i]+=w[now];
            dfs(now+1,cnt);
            cab[i]-=w[now];            
        }
    }
    cab[cnt]=w[now];//重新使用一个缆车 
    dfs(now+1,cnt+1);
    cab[cnt+1]=0;
}
bool cmp(int &a,int &b){
    return a>b;
}
int main(){
    cin>>n>>weight;
    for(int i=0;i<n;i++){
        scanf("%d",&w[i]);
    }
    sort(w,w+n,cmp);//按照weight进行降序排序,优先排比较大的
    dfs(0,0);
    cout<<ans<<endl; 
}

猜你喜欢

转载自www.cnblogs.com/randy-lo/p/13161286.html