CodeVS 4228 小猫爬山 - DFS

传送门

本题为简单的DFS,但需要一些小剪枝。

我们遍历的状态有3个:当前需安放的第i只小猫now、已经花费的钱数cnt、各矿车剩余的空间rst[]。

我们把rst[]作为回溯的状态,把now和cnt作为转移的参数。

先遍历不新建矿车的情况:枚举每个矿车,若能安放,则继续遍历该情况。

再遍历新建矿车的情况。

还要加上一些剪枝:

1.最优性剪枝:若当前cnt已经>=ans,就return。

2.优化搜索顺序:重量大的小猫所能安放的情况比重量小的要少,因此我们可以先对小猫的重量进行降序排序,以缩小搜索树的范围。

AC Code:

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 using namespace std;  5 int n,w;  6 int c[50];  7 int ans=(1<<30);  8 int rst[50];  9 void dfs(int now,int cnt) 10 //now=当前为第i只小猫 cnt=花钱数 11 { 12 if(cnt>=ans) return; 13 if(now==n+1) 14  { 15 ans=min(ans,cnt); 16 return; 17  } 18 for(int i=1;i<=cnt;i++) 19  { 20 if(rst[i]+c[now]<=w) 21  { 22 rst[i]+=c[now]; 23 dfs(now+1,cnt); 24 rst[i]-=c[now]; 25  } 26  } 27 rst[cnt+1]=c[now]; 28 dfs(now+1,cnt+1); 29 rst[cnt+1]=0; 30 } 31 bool cmp(int a,int b) 32 { 33 return a>b; 34 } 35 int main() 36 { 37 scanf("%d%d",&n,&w); 38 for(int i=1;i<=n;i++) 39 scanf("%d",&c[i]); 40 sort(c+1,c+n+1,cmp); 41 dfs(1,0); 42 printf("%d",ans); 43 return 0; 44 } 45 /* 46 5 1996 47 1 48 2 49 1994 50 12 51 29 52 */

 

转载于:https://www.cnblogs.com/Loi-Brilliant/p/8728914.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值