codevs 4228 小猫爬山 【搜索】By cellur925

题目描述 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 }
View Code

 

posted @ 2018-07-30 22:29  cellur925&Chemist  阅读(277)  评论(0编辑  收藏  举报