poj1011 Sticks(DFS+剪枝)
题目链接
http://poj.org/problem?id=1011
题意
输入n根棍子的长度,将这n根棍子组合成若干根长度相同的棍子,求组合后的棍子的最小长度。这题是poj2362的加强版,思路与poj2362相同,只是在2362的基础上添加了剪枝操作,做这题之前先去做poj2362效果最好。
思路
由于棍子越长,组合时的灵活性越差,所以要先从长棍子开始搜索,则首先要将n根棍子从长到短排序,然后从最长的棍子开始dfs。由于棍子最多可以有64根,不剪枝的话肯定会超时。以下是几种剪枝方法:
(1)假设n根棍子中最长的长度为maxLen,n根棍子的长度和为sum,最后求得的结果为len,则len∈[maxLen,sum],且sum%len==0;
(2)由于所有的棍子都降序排序,在组合的过程中若某一棍子不合适,则跳过该棍子后面与其长度相同的所有棍子;
(3)最重要的剪枝:在组合新棍子时,如果添加的第一根棍子stick[i]和剩余的所有棍子都无法组合,则不用继续往下搜索,直接返回(如果继续搜索,到最后stick[i]会被剩下)。
代码
未剪枝代码(超时,dfs部分与poj2362的代码基本相同):
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std; const int INF = <<;
const int N = ;
vector<int> stick;
int visit[N];
int n;
int ans; bool cmp(int a, int b)
{
return a > b; //棍子从长到短排序
} /*
* cur : 当前从第cur根棍子开始尝试组合
* nums : 当前还有nums根新棍子未组合完成
* curLen :当前组合的棍子长度
* len : 要组合的新棍子长度
*/
bool dfs(int cur, int nums, int curLen, int len)
{
if(nums==)
return true; for(int i=cur; i<n; i++)
{
if(visit[i])
continue;
visit[i] = ;
if(curLen+stick[i]<len)
{
if(dfs(cur+, nums, curLen+stick[i], len))
return true;
}
else if(curLen+stick[i]==len)
{
if(dfs(, nums-, , len))
return true;
}
visit[i] = ;
}
return false;
} int main()
{
//freopen("poj1011.txt", "r", stdin);
while(cin>>n && n)
{
int sum = ;
stick.clear();
for(int i=; i<n; i++)
{
int len;
cin>>len;
sum += len;
stick.push_back(len);
} ans = INF;
sort(stick.begin(), stick.end(), cmp);
for(int i=stick[]; i<=sum; i++)
{
if(sum % i != )
continue;
memset(visit, , sizeof(visit));
if(dfs(, sum/i, , i))
{
cout<<i<<endl;
break;
}
}
}
return ;
}
剪枝后代码(AC):
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std; const int INF = <<;
const int N = ;
vector<int> stick;
int visit[N];
int n;
int ans; bool cmp(int a, int b)
{
return a > b; //棍子从长到短排序
} /*
* cur : 当前从第cur根棍子开始尝试组合
* nums : 当前还有nums根新棍子未组合完成
* curLen :当前组合的棍子长度
* len : 要组合的新棍子长度
*/
bool dfs(int cur, int nums, int curLen, int len)
{
if(nums==)
return true; int same = -; //剪枝(2)
for(int i=cur; i<n; i++)
{
if(visit[i] || stick[i]==same)
continue;
visit[i] = ;
if(curLen+stick[i]<len)
{
if(dfs(cur+, nums, curLen+stick[i], len))
return true;
else same = stick[i];
}
else if(curLen+stick[i]==len)
{
if(dfs(, nums-, , len))
return true;
else same = stick[i];
}
visit[i] = ;
if(curLen==) //剪枝(3)
break;
}
return false;
} int main()
{
//freopen("poj1011.txt", "r", stdin);
while(cin>>n && n)
{
int sum = ;
stick.clear();
for(int i=; i<n; i++)
{
int len;
cin>>len;
sum += len;
stick.push_back(len);
} ans = INF;
sort(stick.begin(), stick.end(), cmp);
for(int i=stick[]; i<=sum; i++)
{
if(sum % i != ) //剪枝(1)
continue;
memset(visit, , sizeof(visit));
if(dfs(, sum/i, , i))
{
cout<<i<<endl;
break;
}
}
}
return ;
}
poj1011 Sticks(DFS+剪枝)的更多相关文章
- poj1011 Sticks(dfs+剪枝)
Sticks Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 110416 Accepted: 25331 Descrip ...
- poj1011(DFS+剪枝)
题目链接:https://vjudge.net/problem/POJ-1011 题意:给定n(<=64)条木棍的长度(<=50),将这些木棍刚好拼成长度一样的若干条木棍,求拼出的可能的最 ...
- poj 1011 :Sticks (dfs+剪枝)
题意:给出n根小棒的长度stick[i],已知这n根小棒原本由若干根长度相同的长木棒(原棒)分解而来.求出原棒的最小可能长度. 思路:dfs+剪枝.蛮经典的题目,重点在于dfs剪枝的设计.先说先具体的 ...
- POJ1011 (DFS+剪枝)
Sticks Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 129606 Accepted: 30388 Descrip ...
- POJ 1011 - Sticks DFS+剪枝
POJ 1011 - Sticks 题意: 一把等长的木段被随机砍成 n 条小木条 已知他们各自的长度,问原来这些木段可能的最小长度是多少 分析: 1. 该长度必能被总长整除 ...
- poj1011 && uva307 DFS + 剪枝
将木棒从大到小排列,保证每次的选择都是最长可选的木棒. 剪枝: 1 . 如果第 i 根木棒被选择却无法成功拼接,那么后面与其长度相同的也不能选择. 2 . 如果第 cnt + 1 根木棒无法成功拼接, ...
- hdu 1145(Sticks) DFS剪枝
Sticks Problem Description George took sticks of the same length and cut them randomly until all par ...
- POJ 1011 Sticks dfs,剪枝 难度:2
http://poj.org/problem?id=1011 要把所给的集合分成几个集合,每个集合相加之和ans相等,且ans最小,因为这个和ans只在[1,64*50]内,所以可以用dfs一试 首先 ...
- DFS(剪枝) POJ 1011 Sticks
题目传送门 /* 题意:若干小木棍,是由多条相同长度的长木棍分割而成,问最小的原来长木棍的长度: DFS剪枝:剪枝搜索的好题!TLE好几次,终于剪枝完全! 剪枝主要在4和5:4 相同长度的木棍不再搜索 ...
- poj 1011 Sticks (DFS+剪枝)
Sticks Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 127771 Accepted: 29926 Descrip ...
随机推荐
- mysqldump 和 sql命令导入sql文件
注意:不是进入mysql命令行操作的::: mysqldump -uroot -p --database x3gbk >x3gbk.sql 回车会出发,输入密码; 直接在-p后输入密码,有时候这 ...
- maven创建spring项目之后,启动报错java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener
出错情景:maven中已经加载了spring的核心包,但是项目启动时,报错: org.apache.catalina.core.StandardContext listenerStart严重: Err ...
- HTML5增强的表单
form元素a.用来定义一个表单,是建立表单的基础元素(就类似定义表格的table)b.表单的其他元素包含在form元素中,其主要子元素有:input/button/select......form元 ...
- Nodejs文件监控chokidar
最近有个需求是扫描用例,用例是放在svn上,如果每次扫描都去遍历目录的话会有占用太多的io,所以想着用文件监控,有文件变化时只对该文件进行操作. Nodejs里的 chokidar 模块可以更好的对文 ...
- 开发技巧:高效的使用 Response.Redirect
我正在评估一个 ASP.NET Web 项目应用.它有一些可扩展性问题.意味着当网站访问量增加的时候.系统将会变得缓慢.当我查看应用日志.我找到了大量的 ThreadAbortException. 这 ...
- 一般处理程序、ASP.NET核心知识(5)
初窥 1.新建一个一般处理程序 新建一个一般处理程序 2.看看里头的代码 public class MyHandler : IHttpHandler { public void ProcessRequ ...
- HDU 5995 Kblack loves flag (模拟)
题目链接 Problem Description Kblack loves flags, so he has infinite flags in his pocket. One day, Kblack ...
- HDU 1034 Candy Sharing Game (模拟)
题目链接 Problem Description A number of students sit in a circle facing their teacher in the center. Ea ...
- 蓝色简单的cms文档管理系统模板——后台
链接:http://pan.baidu.com/s/1qYMwHis 密码:xyiw
- 自定义 feign 反序列化时间字符格式
参考 : https://blog.csdn.net/forezp/article/details/73480304 feign client 默认配置类:默认的配置类为FeignClientsCon ...