poj 1011 :Sticks (dfs+剪枝)
题意:给出n根小棒的长度stick[i],已知这n根小棒原本由若干根长度相同的长木棒(原棒)分解而来。求出原棒的最小可能长度。
思路:dfs+剪枝。蛮经典的题目,重点在于dfs剪枝的设计。先说先具体的实现:求出总长度sum和小棒最长的长度max,则原棒可能的长度必在max~sum之间,然后从小到大枚举max~sum之间能被sum整除的长度len,用dfs求出所有的小棒能否拼凑成这个长度,如果可以,第一个len就是答案。
下面就是关键的了,就是这道题dfs的实现和剪枝的设计:
1.以一个小棒为开头,用dfs看看能否把这个小棒拼凑成len长,如果可以,用vis[i]记录下用过的小棒,然后继续以另外一个小棒为开头,以此类推。
2.小棒的长度从大到小排序,这个就不解释了。
3.如果当前最长的小棒不能拼成len长,那么就返回前一步,更改前一步的最长小棒的组合情况(这里不能是全部退出),不用再继续搜索下去了。
4.最重要的,就是比如说17,9,9,9,9,8,8,5,2……如果当前最长小棒为17,它与第一个9组合之后dfs发现不能拼成len,那么17就不用和后面所有的9组合了,而直接和8开始组合。这个剪枝直接从TLE到16MS,很强大。
源代码:(160K 16MS)
#include<iostream>
#include<algorithm>
using namespace std;
const int Max = 65;
int n, len, stick[Max];
bool flag, vis[Max];
bool cmp(int a, int b){
return a> b;
}
void dfs(int dep, int now_len, int u){ // dep为当前已被用过的小棒数,u为当前要处理的小棒。
if(flag) return;
if(now_len == 0){ // 当前长度为0,寻找下一个当前最长小棒。
int k = 0;
while(vis[k]) k ++; // 寻找第一个当前最长小棒。
vis[k] = true;
dfs(dep + 1, stick[k], k + 1);
vis[k] = false;
return;
}
if(now_len == len){ // 当前长度为len,即又拼凑成了一根原棒。
if(dep == n) flag = true; // 完成的标志:所有的n根小棒都有拼到了。
else dfs(dep, 0, 0);
return;
}
for(int i = u; i < n; i ++)
if(!vis[i] && now_len + stick[i]< = len){
if(!vis[i-1] && stick[i] == stick[i-1]) continue; // 不重复搜索:最重要的剪枝。
vis[i] = true;
dfs(dep + 1, now_len + stick[i], i + 1);
vis[i] = false;
}
}
int main(){
while(scanf("%d", &n)&& n != 0){
int sum = 0;
flag = false;
for(int i = 0; i < n; i ++){
scanf("%d", &stick[i]);
sum += stick[i];
}
sort(stick, stick + n, cmp); // 从大到小排序。
for(len = stick[0]; len < sum; len ++)
if(sum % len == 0){ // 枚举能被sum整除的长度。
memset(vis, 0, sizeof(vis));
dfs(0, 0, 0);
if(flag) break;
}
printf("%d\n", len);
}
return 0;
}
poj 1011 :Sticks (dfs+剪枝)的更多相关文章
- POJ 1011 - Sticks DFS+剪枝
POJ 1011 - Sticks 题意: 一把等长的木段被随机砍成 n 条小木条 已知他们各自的长度,问原来这些木段可能的最小长度是多少 分析: 1. 该长度必能被总长整除 ...
- POJ 1011 Sticks dfs,剪枝 难度:2
http://poj.org/problem?id=1011 要把所给的集合分成几个集合,每个集合相加之和ans相等,且ans最小,因为这个和ans只在[1,64*50]内,所以可以用dfs一试 首先 ...
- poj 1011 Sticks ,剪枝神题
木棒 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 118943 Accepted: 27429 Description 乔治拿 ...
- DFS(剪枝) POJ 1011 Sticks
题目传送门 /* 题意:若干小木棍,是由多条相同长度的长木棍分割而成,问最小的原来长木棍的长度: DFS剪枝:剪枝搜索的好题!TLE好几次,终于剪枝完全! 剪枝主要在4和5:4 相同长度的木棍不再搜索 ...
- 搜索+剪枝——POJ 1011 Sticks
搜索+剪枝--POJ 1011 Sticks 博客分类: 算法 非常经典的搜索题目,第一次做还是暑假集训的时候,前天又把它翻了出来 本来是想找点手感的,不想在原先思路的基础上,竟把它做出来了而且还是0 ...
- poj 1011 Sticks (DFS+剪枝)
Sticks Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 127771 Accepted: 29926 Descrip ...
- POJ 1011 Sticks 【DFS 剪枝】
题目链接:http://poj.org/problem?id=1011 Sticks Time Limit: 1000MS Memory Limit: 10000K Total Submissio ...
- OpenJudge 2817:木棒 / Poj 1011 Sticks
1.链接地址: http://bailian.openjudge.cn/practice/2817/ http://poj.org/problem?id=1011 2.题目: 总时间限制: 1000m ...
- uva 215 hdu 1455 uvalive5522 poj 1011 sticks
//这题又折腾了两天 心好累 //poj.hdu数据极弱,找虐请上uvalive 题意:给出n个数,将其分为任意份,每份里的数字和为同一个值.求每份里数字和可能的最小值. 解法:dfs+剪枝 1.按降 ...
随机推荐
- eval()和exec()函数的区别
(1)eval(str [,globals [,locals ])函数将字符串str当成有效Python表达式来求值,并返回计算结果.(2)exec()函数将字符串str当成有效的Python表达式来 ...
- 母版页改变被嵌套的页面中的控件ID的解决方法
使用过模板页的朋友都会很纳闷,怎么页面的用js通过getElementById(“id”):找不到对象.查看了页面源代码才发现,原来控件的ID变了,这是母版页导致的.因为母版页怕母版页本身页面中的控件 ...
- CSS ,浮动,clear记录,和一些转载别处
DIV+CSS clear both清除产生浮动 我们知道有时使用了css float浮动会产生css浮动,这个时候就需要清理清除浮动,我们就用clear样式属性即可实现. clear 属性规定元素的 ...
- js引入方式的弹框方法2
html代码: <!DOCTYPE html> <html lang="zh-CN"> <head> <meta http-equiv=& ...
- django startapp报 maximum recursion depth exceeded
报错截图如下: 解决办法:修改指定路径下的functools.py文件的def total_ordering(cls):方法: 原来的样子: convert = { '__lt__': [('__gt ...
- 常用代码块:java使用剪贴板复制文本
// 获得系统剪切板 Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); // 复制到剪切板上 String ...
- python并发之IO模型(一)
事件驱动模型 协程:遇到IO操作就切换. 但什么时候切回去呢?怎么确定IO操作完了? 很多程序员可能会考虑使用“线程池”或“连接池”.“线程池”旨在减少创建和销毁线程的频率,其维持一定合理数量的线程, ...
- django-admin 修改admin自带模版
还不知道怎么指定修改每个页面,我就把把所有修改写在一个页面,通过url进行判断是否是是否显示修改内容,修改的是change_form.html ,在admin里面可以找到 {% block objec ...
- [不常用] - CSRF(跨站点请求伪造)
CSRF,Cross Site Request Forgery,即跨站点请求伪造. 这种攻击是指,在用户正常登录系统以后,攻击者诱使用户访问一些非法链接,以执行一些非法操作. 比如:如果删除用户操 ...
- Python学习进程(6)函数
函数最重要的目的是方便我们重复使用相同的一段程序. (1)函数的定义: 函数定义的简单规则: 1.函数代码块以 def 关键词开头,后接函数标识符名称和圆括号(): 2.任何传入参数和 ...