题目描述
Description
Freda和rainbow饲养了N只小猫,这天,小猫们要去爬山。经历了千辛万苦,小猫们终于爬上了山顶,但是疲倦的它们再也不想徒步走下山了(呜咕>_<)。
Freda和rainbow只好花钱让它们坐索道下山。索道上的缆车最大承重量为W,而N只小猫的重量分别是C1、C2……CN。当然,每辆缆车上的小猫的重量之和不能超过W。每租用一辆缆车,Freda和rainbow就要付1美元,所以他们想知道,最少需要付多少美元才能把这N只小猫都运送下山?
日常刷lyd书系列。qwq。
个人觉得是一道不错的搜索入门题(没错我学搜索近九个月仍处于入门阶段qwq)。
先总结一下,(目前)感觉搜索有两种:求最值/求方案数。
前者如本题,搜索时分两种情况,保持当前的最优解,迫不得已向下开。每次搜索结束子状态后,还原子状态原状。
dfs函数传的参数是什么?当前需要的状态。在本题中,我们关心的就是已经运送的小猫数,用的缆车数量,各缆车目前载重量。最后者,我们可以用数组来记录。搜索边界是当在运送的小猫now==n+1.
两个小剪枝:先按小猫重量从大往小排序,优先搜索更大的小猫;因为我们dfs的过程实际在不断更新最优解,所以当现在搜出来的结果大于等于可行解就可以停止搜索了,因为它一定不会成为更优解。
code
1 #include<cstdio> 2 #include<algorithm> 3 4 using namespace std; 5 typedef long long ll; 6 7 int n,limit; 8 int w[100]; 9 int ans,pos[100]; 10 11 bool cmp(int a,int b) 12 { 13 return a>b; 14 } 15 16 void dfs(int now,int cnt) 17 { 18 if(cnt>=ans) return ; 19 if(now==n+1) 20 { 21 ans=min(ans,cnt); 22 return ; 23 } 24 for(int i=1;i<=cnt;i++) 25 if(pos[i]+w[now]<=limit) 26 { 27 pos[i]+=w[now]; 28 dfs(now+1,cnt); 29 pos[i]-=w[now]; 30 } 31 pos[cnt+1]=w[now]; 32 dfs(now+1,cnt+1); 33 pos[cnt+1]=0; 34 } 35 36 int main() 37 { 38 scanf("%d%d",&n,&limit); ans=n; 39 for(int i=1;i<=n;i++) scanf("%d",&w[i]); 40 sort(w+1,w+1+n,cmp); 41 // for(int i=1;i<=n;i++) printf("%d ",w[i]); 42 // printf("\n"); 43 dfs(1,0); 44 printf("%d",ans); 45 return 0; 46 }