【洛谷】P1120 小木棍[数据加强版]
来源:互联网 发布:js聚合物水泥防水阴角 编辑:程序博客网 时间:2024/04/30 12:07
传送门
这道题目因为加强了数据,所以博客以前的题解不能够满足这道题目的时间复杂度,当然还是使用暴力,但是得多一点剪枝。
- 剪枝1:将木棍从大到小排序,这样搜索就可以少一些可能性。
- 剪枝2:从最大的一根木棍开始枚举,一直到木棍长度之和/2,因为最糟糕的情况就是每一根木棍只与自己搭配,所以这种情况在最后输出,再就是两两搭配,所以答案就是总和/2,这样可以减去差不多一半的复杂度。
- 剪枝3:如果前
t−1 个木棍都订好了,最后一根木棍想都不用想都可以搭配。 - 剪枝4:缩小搜索范围,但是要记得每一次
s==m 的时候初始化。 - 剪枝5:如果着一根木棍被用过了,或者是它与当前木棍之和加起来超过了我们想要的木棍总长,就不选它。
- 剪枝6:如果我当前的木棍和上一个木棍是一样的,而且上面一根木棍不能够凑出答案,那我这一根也不行!
- 剪枝7:如果我当前的长度,加上后面所有的木棍的长度都凑不出来一个总木棍长,就可以放弃这种方法。
- 剪枝8:如果当前状态(新的)搜索不出来一根新木棍,就反悔。
- 剪枝9:如果我现在这根木棍加上总和才可以凑出
m ,那么后面就凑不出来了!
具体看代码:
//洛谷P1120 小木棍#include<cstdio>#include<cstdlib>#include<algorithm>int n,cnt,sum,maxx,t,m;int a[100],p[110];bool b[100];using namespace std;int cmp(const int&a,const int&b) { return a>b;}void dfs(int l,int s,int last) { if(s==m) {//如果找好了一根木棍 s=0;//累加器清零 l++;//累记的以前的总木棍个数+1 last=1;//下次从第一个木棍开始搜索 } if(l==t-1) {//这是第3个剪枝 printf("%d\n",m);exit(0); } for(int i=last; i<=cnt; i++) {//这是第4个剪枝 if(s+a[i]>m||b[i]) continue;//这是一个可行性剪枝[剪枝5] if(a[i]==a[i-1]&&!b[i-1]) continue;//这是第6个剪枝 if(s+p[i]<m)return;//这是第7个剪枝[很重要!] b[i]=1; dfs(l,s+a[i],i+1); b[i]=0;//这是普通搜索加回溯 if(s==0)return;//这是第8个剪枝 if(s+a[i]==m)return;//这是第9个剪枝 }}void init() { int x; for(int i=1; i<=n; i++) { scanf("%d",&x); if(x<=50) { a[++cnt]=x;//重新挑选 sum+=x;//累加 maxx=max(maxx,x);//计算最大值 } }}int main() { int i,j,k; scanf("%d",&n); init();//读入,这里记住一定要排除50以上的! sort(a+1,a+n+1,cmp);//第1个剪枝 for(i=n;i>=1;i--) p[i]=p[i+1]+a[i];//计算一个后缀和,剪枝需要 for(i=maxx; i<=sum/2; i++) {//第2个剪枝 if(sum%i==0) {//如果它有成为答案的可能才搜索,不要浪费时间 t=sum/i;//这个表示以前总的木棍个数 m=i;//这是以前木棍的长度 dfs(0,0,0);//搜索 } } printf("%d\n",sum);//如果循环结束了程序还没有结束,就只能输出这个,见上分析 return 0;}
这道题目很适合练习剪枝的同学们做,确实是有些复杂,但是应该有比我这个代码更快的[二分答案],希望大家能够写出来!
阅读全文
0 0
- 【洛谷】P1120 小木棍[数据加强版]
- P1120 小木棍 数据加强版
- P1120 小木棍(数据加强版)
- P1120 小木棍 [数据加强版]
- 洛谷 P1120 小木棍 [数据加强版 ]
- 洛谷 P1120 小木棍 [数据加强版]
- 【搜索】洛谷 P1120 小木棍 [数据加强版]
- 洛谷p1120小木棍【数据加强版】c++
- P1120 小木棍 [数据加强版]
- P1120 小木棍 [数据加强版]
- luogu P1120 小木棍 [数据加强版]
- 洛谷P1120 小木棍[数据加强版](回溯法)
- 洛谷P1120 小木棍
- 洛谷 【P1120】 小木棍
- [P1120]小木棍
- 洛谷 1120 小木棍 [数据加强版]
- 小木棍 [数据加强版]
- 洛谷1120 小木棍 [数据加强版] dfs+剪枝(史上最详尽)
- Win7下基于Anaconda安装TensorFlow
- weui学习总结——2、操作反馈
- 改变,从此刻开始
- RxJS简介
- linux系统下调试程序经验总结
- 【洛谷】P1120 小木棍[数据加强版]
- SpringMVC流程架构图
- SSM配置之三Spring
- 自定义下载的封装实现
- 技能CD与Toggle按钮设置
- usb无法传输大于4g文件怎么办?
- 149. Max Points on a Line
- Oracle学习笔记(七)操作表中的数据
- 物体检测及分类方法总结