题目链接:https://vjudge.net/problem/POJ-1011

题意:给定n(<=64)条木棍的长度(<=50),将这些木棍刚好拼成长度一样的若干条木棍,求拼出的可能的最小长度。

思路:经典的DFS剪枝题,这道题的剪枝技巧很关键。

  数据不大,可以想到枚举木棍所有可能的长度,然后利用dfs来查找所有可能的搭配情况,dfs的参数len表示当前的木棍长度,rest表示还需要的长度,pos表示当前搜到的下标,num表示原始木棍中剩余没有匹配的数量,搜索的终止条件为rest==0&&num==0,但直接这样做还是会超时,这道题有许多的剪枝技巧:

  1. 将序列降序排序,方便后面的剪枝。

  2. 枚举的范围是[Max,sum/2],其中Max为序列中的最大值,sum为序列和。

  3. 可能的长度只能是sum的约数。

  4. 深搜时,如果在寻找一条新木棍时使用了剩余木棍中最长的也不能满足条件,则直接返回。因为最长的一根一定要使用,不用的话后面也一直用不到,最终是无法成功匹配的。对应代码中的if(!rest)中的语句。

  5. 深搜时,如果当前木棍刚好使正在凑的木棍形成新木棍,但也不满足条件时,直接返回。比如你现在是3,使用3刚好能凑出一根新木棍,但使用之后后面仍无法满足条件,现在即使后面存在1 2,你使用1 2来凑出剩下的3也一定不能满足条件,因为1 2两条木棍比3更灵活,使用1 2都无法成功的话使用3更无法成功。对应代码if(a[i]==rest) break。

  6. 当前木棍长为x,使用x无法满足条件时,则可直接跳过后面所有长为x的木棍。对应代码while(a[i+1]==a[i]) ++i。

AC代码:

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std; int n,a[],vis[],ans; bool cmp(int x,int y){
return x>y;
} bool dfs(int len,int rest,int pos,int num){
if(!rest&&!num){
ans=len;
return true;
}
if(!rest){
rest=len;
for(int i=;i<n;++i){
if(vis[i]) continue;
vis[i]=;
if(dfs(len,rest-a[i],i+,num-))
return true;
vis[i]=;
return false;
}
}
for(int i=pos;i<n;++i){
if(vis[i]) continue;
if(a[i]<=rest){
vis[i]=;
if(dfs(len,rest-a[i],i+,num-))
return true;
vis[i]=;
if(a[i]==rest) break;
while(a[i+]==a[i]) ++i;
}
}
return false;
} int main(){
while(scanf("%d",&n),n){
int sum=,flag=;
for(int i=;i<n;++i){
scanf("%d",&a[i]);
sum+=a[i];
}
sort(a,a+n,cmp);
memset(vis,,sizeof(vis));
for(int i=a[];i<=sum/;++i){
if(sum%i==){
if(dfs(i,i,,n)){
flag=;
break;
}
}
}
if(flag)
printf("%d\n",ans);
else
printf("%d\n",sum);
}
return ;
}

  

poj1011(DFS+剪枝)的更多相关文章

  1. *HDU1455 DFS剪枝

    Sticks Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Subm ...

  2. POJ 3009 DFS+剪枝

    POJ3009 DFS+剪枝 原题: Curling 2.0 Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 16280 Acce ...

  3. poj 1724:ROADS(DFS + 剪枝)

    ROADS Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10777   Accepted: 3961 Descriptio ...

  4. DFS(剪枝) POJ 1011 Sticks

    题目传送门 /* 题意:若干小木棍,是由多条相同长度的长木棍分割而成,问最小的原来长木棍的长度: DFS剪枝:剪枝搜索的好题!TLE好几次,终于剪枝完全! 剪枝主要在4和5:4 相同长度的木棍不再搜索 ...

  5. DFS+剪枝 HDOJ 5323 Solve this interesting problem

    题目传送门 /* 题意:告诉一个区间[L,R],问根节点的n是多少 DFS+剪枝:父亲节点有四种情况:[l, r + len],[l, r + len - 1],[l - len, r],[l - l ...

  6. HDU 5952 Counting Cliques 【DFS+剪枝】 (2016ACM/ICPC亚洲区沈阳站)

    Counting Cliques Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

  7. HDU 5937 Equation 【DFS+剪枝】 (2016年中国大学生程序设计竞赛(杭州))

    Equation Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  8. LA 6476 Outpost Navigation (DFS+剪枝)

    题目链接 Solution DFS+剪枝 对于一个走过点k,如果有必要再走一次,那么一定是走过k后在k点的最大弹药数增加了.否则一定没有必要再走. 记录经过每个点的最大弹药数,对dfs进行剪枝. #i ...

  9. poj 1011 Sticks (DFS+剪枝)

    Sticks Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 127771   Accepted: 29926 Descrip ...

随机推荐

  1. 注意vue-router嵌套路由的问题:子路由组件中的class名和本组件页面的class名相同时,子路由组件的样式被覆盖。

    注意vue-router嵌套路由的问题:子路由组件中的class样式被覆盖,当需要用到路由嵌套时,clas命名时注意不要相同. 点击查看上一篇vue-router嵌套路由具体 例子: 子路由a组件中: ...

  2. python基础语法-Ⅲ

    Python注释 python中单行注释采用 # 开头. 实例 输出结果: 注释可以在语句或表达式行末: python 中多行注释使用三个单引号(''')或三个双引号(""&quo ...

  3. C语言 - 堆和栈

    一.堆内存 1.就是程序员手动管理的一块内存,在C语言中,可以理解为用malloc.realloc等申请空间的一些函数,这些函数所申请的空间就是堆空间 2.C语言中,堆空间是申请和释放 malloc/ ...

  4. TTTTTTTTTTTTTT poj 1127 Jack Straws 线段相交+并查集

    题意: 有n个木棍,给出木棍的两个端点的x,y坐标,判断其中某两个线段是否连通(可通过其他线段连通) #include <iostream> #include <cstdio> ...

  5. luoguP3353 在你窗外闪耀的星星

    P3353 在你窗外闪耀的星星 题目描述 飞逝的的时光不会模糊我对你的记忆.难以相信从我第一次见到你以来已经过去了3年.我仍然还生动地记得,3年前,在美丽的集美中学,从我看到你微笑着走出教室,你将头向 ...

  6. linux crontab 定时任务,任务命令单独linux执行正常,放定时任务就不执行了,解决办法 (原)

    这是我crontab里面的内容 */30 * * * *  ./usr/bin/wget -q -O sync_log.txt http://fly.dllm.cn/index.php/Home/In ...

  7. 3分割线左右间距(LinearLayoutManager.VERTICAL)

    <?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android=" ...

  8. 20175215 2018-2019-2 第一周Linux虚拟机环境调试及java程序调试学习总结

    一.Linux虚拟机的java环境调试 之前直接在终端中使用export直接配置java的运行环境,导致每次终端被重启的时候都要重新配置java的运行环境,直到看到老师的博客Intellj IDEA ...

  9. java 开发工具包 jdk 64位 jdk-8u221-windows-x64.exe 迅雷下载

    迅雷下载链接(迅雷新建任务,复制链接进去): https://download.oracle.com/otn/java/jdk/8u221-b11/230deb18db3e4014bb8e3e8324 ...

  10. Windows下的Crontab表达式解析DLL的使用

    Linux的crontab工具特别的好用,正好现在工作总有好多定时执行的事 用Windows的定时任务觉得特别Low,哈哈,用C#写个任务触发器 然后再用上Crontab表达式解析DLL,觉得马上就高 ...