hdu 1455 Sticks(dfs+剪枝)
题目大意:
George有许多长度相同的木棍,随机的将这些木棍砍成小木条,每个小木条的长度都是整数单位(长度区间[1, 50])。现在George又想把这些小木棒拼接成原始的状态,但是他忘记了原来他有多少根木棍,也忘记了木棍的长度。现在请你编写一个程序,找到最短的原始的木棍长度。
输入:
每个测试案例包含两行,第一行表示小木条的总个数(最多64根小木条),第二行表示每个小木条的长度,用空格分开。当第一行输入为零的时候表示程序结束。
输出:
对于每个测试案例输出最短的木棍长度。
解题思路:
用搜索算法去解决问题需要知道搜索的区间和剪枝条件,现在木棍长度未知,木棍个数未知,对于我们搜索是不利的。需要从已知条件推导到一个可以搜索的区间,然后再仔细思考如何剪枝来减少时间复杂度。
小木条是从木棍上砍下来的 => 木棍长度的下限:最长的小木条长度(part_max)
小木条的个数和长度已知 => 木棍长度的上限:所有小木条长度之和(part_sum)
确定搜索区间:木棍长度(stick_len) ∈ [part_max, part_sum] 并且 stick_len ∈ 整数
确定了stick_len => 确定了木棍的个数(stick_num)
剪枝1:当确定一个stick_len时候,那么这个stick_len要能整除part_sum,否则不能组成整数stick_num
剪枝2:见AC代码分析
剪枝3:见AC代码分析
AC代码:
// 19472897 2017 - 01 - 02 12:45 : 00 Accepted 1455 15MS 1724K 2328 B C++ 潮州牛肉丸
#include <stdio.h>
#include <algorithm>
#include <functional> int n; // the number of parts
int part[]; // the parts at most 64
int visit[]; // mark the situation of already used parts
int part_sum = ; // 所有小木条的长度之和
int stick_num = ; // 木棍的个数
int stick_len = ; // 木棍的长度 void init()
{
part_sum = ;
stick_num = ;
memset(part, , sizeof(part));
memset(visit, , sizeof(visit));
} // count:已经拼接好的木棍数,len:正在拼接的木棍长度,index:上一次搜索下标位置
bool dfs(int count, int len, int index)
{
if (stick_num == count)
return true; for (int i = index + ; i < n; ++i)
{
if (true == visit[i])
continue;
if (len + part[i] == stick_len)
{
visit[i] = true;
if (true == dfs(count + , , -))
return true;
visit[i] = false;
return false;
}
else if (len + part[i] < stick_len)
{
visit[i] = true;
if (true == dfs(count, len + part[i], i))
return true;
visit[i] = false; /* 已知条件:
1、stick的长度(stick_num)和个数(stick_num)
2、dfs已经返回false
*/ /* 剪枝2:当dfs返回false,len等于0的时候,stick的长度不是题目的正确结果,
后面的搜索无意义,直接返回false。 根据原则:如果当前搜索用的stick长度是题目的正确结果,那么所有的part都一定要被用上。
然而拼接一根新stick的时候(即len的值为0,表示当前正在拼接一根新stick),选取
的第一根part无论如何都能被用上,只是后面的part去配合第一根part完成一根stick,
如果在用第一根part的时候,dfs任然返回false,表示这个part不能被用上拼接stick。
与原则相违背。
*/
if ( == len)
return false; /* 剪枝3:
当前状态:dfs返回false,说明part[i]这根木条在当前count,len状态不可用,
接下来搜索的part[i+1]如果与之前的part[i]长度相同也一定不可用,注意我们是把part按降序排序过的*/
while (i < n && part[i] == part[i + ])
++i;
}
}
return false;
} int main(void)
{
while (scanf("%d", &n) != EOF && != n)
{
init();
for (int i = ; i < n; ++i)
{
scanf("%d", &part[i]);
part_sum += part[i]; //记录所有小木条长度之和
} std::sort(part, part + n, std::greater<int>()); // 按照降序排序 // stick的可能长度区间:[最长的小木条长度,所有小木条长度之和]
for (stick_len = part[]; stick_len < part_sum; ++stick_len)
{
if ( == part_sum % stick_len) //剪枝1:木棍的长度一定要能整除所有小木条长度之和
{
stick_num = part_sum / stick_len; // 得到stick的个数
if (true == dfs(, , -))
break;
}
} printf("%d\n", stick_len);
}
return ;
}
hdu 1455 Sticks(dfs+剪枝)的更多相关文章
- HDU 1455 Sticks(经典剪枝)
Sticks Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Sub ...
- hdu 1145(Sticks) DFS剪枝
Sticks Problem Description George took sticks of the same length and cut them randomly until all par ...
- hdu 1455 Sticks
Sticks Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit Statu ...
- poj 1011 :Sticks (dfs+剪枝)
题意:给出n根小棒的长度stick[i],已知这n根小棒原本由若干根长度相同的长木棒(原棒)分解而来.求出原棒的最小可能长度. 思路:dfs+剪枝.蛮经典的题目,重点在于dfs剪枝的设计.先说先具体的 ...
- poj1011 Sticks(dfs+剪枝)
Sticks Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 110416 Accepted: 25331 Descrip ...
- hdu - 1072(dfs剪枝或bfs)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1072 思路:深搜每一个节点,并且进行剪枝,记录每一步上一次的s1,s2:如果之前走过的时间小于这一次, ...
- POJ 1011 - Sticks DFS+剪枝
POJ 1011 - Sticks 题意: 一把等长的木段被随机砍成 n 条小木条 已知他们各自的长度,问原来这些木段可能的最小长度是多少 分析: 1. 该长度必能被总长整除 ...
- HDU 1175 连连看 (DFS+剪枝)
<题目链接> 题目大意:在一个棋盘上给定一个起点和终点,判断这两点是否能通过连线连起来,规定这个连线不能穿过其它的棋子,并且连线转弯不能超过2次. 解题分析:就是DFS从起点开始搜索,只不 ...
- hdu 1044(bfs+dfs+剪枝)
Collect More Jewels Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Othe ...
随机推荐
- 来自 Thoughtram 的 Angular 2 系列资料
Angular 2 已经正式 Release 了,Thoughtram 已经发布了一系列的文档,对 Angular 2 的各个方面进行深入的阐释和说明. 我计划逐渐将这个系列翻译出来,以便对大家学习 ...
- Linux内核模块设计
内核的设计有两种方式:单内核和微内核,两者各有优劣,关于两者的比较可以参见wiki.windowds和Solaris采用微内核结构. Linux内核采用单内核结构,设计比较简单,但单内核的理念是把所有 ...
- Access restriction错误解决办法
Access restriction错误, XX方法 is not accessible due to restriction on required library XXlib 解决方案: Ecli ...
- how to enable remote access for root user
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'password' WITH GRANT OPTION;
- tomcat出现的PermGen Space问题
java.lang.OutOfmemoryError: PermGen Space 的错误,导致项目无法正常运行. 出现这个错误的原因,总结一下: PermGen Space指的是内存的永久保存区,该 ...
- nodejs——qureystring的作用
当node服务器向另一个服务器发送数据时,首先要转换成字符串再post或者get,这个时候就要用到node内置的这个包querystring, querystring.stringify(data);
- 针对APP的测试过程和重点关注内容,做以下梳理和总结
转载自金阳光测试:http://blog.sina.com.cn/s/blog_12df1b9e60102vy57.html 1. 首先是测试资源确认及准备 (1)产品需求文档.产品原型图.接口说 ...
- VS2013配置WTL91_5321_Final
网上关于WTL的文章,尤其是中文的文章不多,根据收集的资料整理出了VS2013安装WTL的方法. .下载.文件很小的,地址:http://sourceforge.net/projects/wtl/fi ...
- oracle驱动问题
转载 http://sosuny.iteye.com/blog/806390
- css之z-index
要想z-index可以使用,就要配合定位元素使用即position 如果定位元素z-index没有发生嵌套: 1.后来居上的准则 2.哪个大,哪个上 例如 如果定位元素z-index发生嵌套: 1.祖 ...