《算法竞赛进阶指南》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; }
每一个不曾起舞的日子,都是对生命的辜负。