当前位置:   article > 正文

蓝桥杯2023年-买瓜(dfs,类型转换同样耗时)_小蓝正在一个瓜摊上买瓜。瓜摊上共有 n 个瓜,每个瓜的重量为a。小蓝刀功了得,

小蓝正在一个瓜摊上买瓜。瓜摊上共有 n 个瓜,每个瓜的重量为a。小蓝刀功了得,

题目描述

小蓝正在一个瓜摊上买瓜。瓜摊上共有 n 个瓜,每个瓜的重量为 Ai 。

小蓝刀功了得,他可以把任何瓜劈成完全等重的两份,不过每个瓜只能劈一刀。

小蓝希望买到的瓜的重量的和恰好为 m 。

请问小蓝至少要劈多少个瓜才能买到重量恰好为 m 的瓜。如果无论怎样小蓝都无法得到总重恰好为 m 的瓜,请输出 −1 。

思路

朴素做法:

dfs每个瓜,有三种选择:

1.选瓜

2.劈瓜,选瓜

3.不选瓜

则复杂度为3^n,也就是3^30,大概2e14,绝对会超时。

所以需要剪枝优化

剪枝优化:

1.如果当前已有重量>所需重量,则剪枝

2.如果当前已有重量+剩下的重量总和<所需重量,剪枝,(求剩下的重量可以用后缀和数组优化)

3.如果当前已经劈过的次数>=目前的劈瓜的最小次数,剪枝

细枝末节:

还有一些细枝末节可优化:

1.除2的话可能会有小数,但是浮点数运算会慢很多,所以我们可以通过放大(乘2)原重量与所需重量。这样就可以只使用整型运算了。(也可以用两个数组分别存储放大后的重量与相应的减半的数量,这样可以在每次搜索时减少一次运算,不过应该影响不大)

2.将重量从大到小排序,这样可以提前排除许多剪枝。

3.强制类型转换的耗时也不少。(int转long之类的)(这一点是我没有想到的,也是我卡题的原因,经过不断不断一直一直反反复复的比对题解代码后才发现的。)

大家可以感受一下:

有转换的耗时,结果超时一半多

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int a[33];//原重
  4. int b[33];//半重
  5. long latter[33];
  6. int m;
  7. int n;
  8. int ans=100;
  9. void dfs(int u,int sum,int k){//sum为int类型时,long与int进行加减时会进行一次类型转换
  10. if(u==n||sum>=m||k>=ans||latter[u]+sum<m){
  11. if(sum==m)ans=min(ans,k);
  12. return ;
  13. }
  14. dfs(u+1,sum+a[u],k);
  15. dfs(u+1,sum+b[u],k+1);
  16. dfs(u+1,sum,k);
  17. }
  18. int main()
  19. {
  20. cin>>n>>m;m*=2;
  21. for(int i=0;i<n;i++){
  22. cin>>b[i];
  23. a[i]=b[i]*2;
  24. }
  25. sort(a,a+n,greater<int>());
  26. sort(b,b+n,greater<int>());
  27. for(int i=n-1;i>=0;i--)
  28. latter[i]=latter[i+1]+a[i];
  29. dfs(0,0,0);
  30. if(ans!=100)
  31. cout<<ans;
  32. else cout<<-1;
  33. }

没有类型转换的,成功通过,二者时间整整相差一倍

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int a[33];//原重
  4. int b[33];//半重
  5. long latter[33];
  6. int m;
  7. int n;
  8. int ans=100;
  9. void dfs(int u,long sum,int k){//sum为long类型时,没有类型转换的耗时
  10. if(u==n||sum>=m||k>=ans||latter[u]+sum<m){
  11. if(sum==m)ans=min(ans,k);
  12. return ;
  13. }
  14. dfs(u+1,sum+a[u],k);
  15. dfs(u+1,sum+b[u],k+1);
  16. dfs(u+1,sum,k);
  17. }
  18. int main()
  19. {
  20. cin>>n>>m;m*=2;
  21. for(int i=0;i<n;i++){
  22. cin>>b[i];
  23. a[i]=b[i]*2;
  24. }
  25. sort(a,a+n,greater<int>());
  26. sort(b,b+n,greater<int>());
  27. for(int i=n-1;i>=0;i--)
  28. latter[i]=latter[i+1]+a[i];
  29. dfs(0,0,0);
  30. if(ans!=100)
  31. cout<<ans;
  32. else cout<<-1;
  33. }

也不排除是测评机的原因,不过以后最好还是减少类似的类型转换更保险一些。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/489403
推荐阅读
相关标签
  

闽ICP备14008679号