DFS(7)——poj1011Sticks
一、题目回顾
题目链接:Sticks

题意:给出一定数量的小木棒的长度,它是由等长的若干木棒随意砍断所得到的。对于给定的一组小木棒,请求出原始木棒的最小长度。
二、解题思路
- DFS+剪枝
- 本题剪枝不到一定火候将会TLE,只有完成一定的剪枝才能AC
本题,我将从我做这题的角度,将所思所想具体记录下来,详细的官版思想见我另一个题解。
首先,看main函数:
int main()
{
while(scanf("%d",&n) && n){
int sum=0;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
sum += a[i]; //记录现在所有木棒的长度之和
}
sort(a+1,a+1+n,cmp); //将数组a中的元素从大到小排列
int len;
flag = 0;
//原木棒长度一定大于等于现在的任何一支木棒(即大于等于最长的木棒)
//原木棒长度一定小于等于现在所有木棒的长度之和
for(len=a[1];len<=sum;len++){ //a[1]为最长木棒的长度
if(sum%len==0){ //原木棒的根数一定是个整数
memset(vis,0,sizeof(vis));
dfs(len,0,n); //假设原木棒长度为len,要拼的原木棒已拼成的长度为0,还有n根木棒
if(flag==1){ //已经拼成功,就退出,因为要原木棒尽可能短
break;
}
}
}
printf("%d\n",len); //打印原木棒的长度
}
return 0;
}
做到这,我在思考,如果原木棒的根数大于1,那么在第一根原木棒拼完之后,我该如何确定第二根,第三根,…
【dfs形参的确定】
- len 假设的原木棒的长度
- now 现在拼的长度(在一根原木棒之内)
- num 剩下的小木棒数目
再看dfs的代码:
void dfs(int len,int now,int num) //预设的原木棒的长度 正在完成的木棒的长度 剩余的小木棒数量
{
if(num==0){
flag = 1;
return;
}
if(now==len) dfs(len,0,num);
for(int i=1;i<=n;i++){
if(!vis[i] && a[i]+now<=len){
vis[i] = 1;
dfs(len,a[i]+now,num-1);
if(flag==1) return;
vis[i] = 0; if(a[i]==len-now || len==len-now) //此剪枝一开始没想到,超时
break;
}
}
}
形参中的三个数必须要在函数体内起到一定的作用。
回答上面的疑惑,我们不再判断是有几根,而是将num==0作为递归出口,当木棒没了,说明拼接成功了。而如果一根原木棒拼接完成,就继续深搜。
这里面一个剪枝一开始我没想到,一直TLE,具体解释见我另一个题解。
题外话:这种题目,自己实践慢慢领悟吧。
三、代码
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std; int n,flag;
int a[];
bool vis[]; bool cmp(const int a, const int b)
{
return a>b;
}
void dfs(int len,int now,int num) //预设的原木棒的长度 正在完成的木棒的长度 剩余的小木棒数量
{
if(num==){
flag = ;
return;
}
if(now==len) dfs(len,,num);
for(int i=;i<=n;i++){
if(!vis[i] && a[i]+now<=len){
vis[i] = ;
dfs(len,a[i]+now,num-);
if(flag==) return;
vis[i] = ; if(a[i]==len-now || len==len-now) //此剪枝一开始没想到,超时
break;
}
}
}
int main()
{
while(scanf("%d",&n) && n){
int sum=;
for(int i=;i<=n;i++){
scanf("%d",&a[i]);
sum += a[i]; //记录现在所有木棒的长度之和
}
sort(a+,a++n,cmp); //将数组a中的元素从大到小排列
int len;
flag = ;
//原木棒长度一定大于等于现在的任何一支木棒(即大于等于最长的木棒)
//原木棒长度一定小于等于现在所有木棒的长度之和
for(len=a[];len<=sum;len++){ //a[1]为最长木棒的长度
if(sum%len==){ //原木棒的根数一定是个整数
memset(vis,,sizeof(vis));
dfs(len,,n); //假设原木棒长度为len,要拼的原木棒已拼成的长度为0,还有n根木棒
if(flag==){ //已经拼成功,就退出,因为要原木棒尽可能短
break;
}
}
}
printf("%d\n",len); //打印原木棒的长度
}
return ;
}
DFS(7)——poj1011Sticks的更多相关文章
- DFS(深度优先)算法编程实践
DFS定义 DFS(Depth-First-Search)深度优先搜索算法,是搜索算法的一种.是一种在开发爬虫早期使用较多的方法.它的目的是要达到被搜索结构的叶结点 . 特点 每次深度优先搜索的结果必 ...
- 拓扑排序+DFS(POJ1270)
[日后练手](非解题) 拓扑排序+DFS(POJ1270) #include<stdio.h> #include<iostream> #include<cstdio> ...
- DFS(一):深度优先搜索的基本思想
采用搜索算法解决问题时,需要构造一个表明状态特征和不同状态之间关系的数据结构,这种数据结构称为结点.不同的问题需要用不同的数据结构描述. 根据搜索问题所给定的条件,从一个结点出发,可以生成一个或多个新 ...
- 深度优先搜索DFS(一)
实例一 0/1背包问题: 有n件物品,每件物品的重量为w[i],价值为c[i].现在需要选出若干件物品放入一个容量为V的背包中,使得在选入背包的物品重量和不超过容量V的前提下,让背包中的物品 ...
- 万能的搜索--之DFS(二)
(一)深度优先搜索(DFS) 我们先给出深度优先的解决办法,所谓深度优先搜索,在迷宫问题里就是不撞南墙不回头,能走得深一点就尽量深一点.如果碰到了墙壁就返回前一个位置尝试其他的方向.在<啊哈!算 ...
- DFS(二):骑士游历问题
在国际象棋的棋盘(8行×8列)上放置一个马,按照“马走日字”的规则,马要遍历棋盘,即到达棋盘上的每一格,并且每格只到达一次.例如,下图给出了骑士从坐标(1,5)出发,游历棋盘的一种可能情况. [例1] ...
- DFS(四):剪枝策略
顾名思义,剪枝就是通过一些判断,剪掉搜索树上不必要的子树.在采用DFS算法搜索时,有时候我们会发现某个结点对应的子树的状态都不是我们要的结果,这时候我们没必要对这个分支进行搜索,砍掉这个子树,就是剪枝 ...
- DFS(三):八皇后问题
[例1]八皇后问题. 在一个8×8国际象棋盘上,放置8个皇后,每个皇后占一格,要求皇后间不会出现相互“攻击”的现象,即不能有两个皇后处在同一行.同一列或同一对角线上.问共有多少种不同的放置方法? (1 ...
- 【递归入门】组合+判断素数:dfs(递归)
题目描述 已知 n 个整数b1,b2,…,bn,以及一个整数 k(k<n).从 n 个整数中任选 k 个整数相加,可分别得到一系列的和. 例如当 n=4,k=3,4 个整数分别为 3,7,12, ...
随机推荐
- mssql数据库迁移到mysql
使用mysql migration toolkit工具来进行迁移.(需要安装jdk6 java的安装包) 发现数据量大的表却没能迁过来.软件使用比较容易,配置下源数据库信息,和目标数据库信息就可以进行 ...
- 菜鸟笔记 -- Chapter 6.2.3 成员变量
6.2.3 成员变量 在Java中对象的属性也称为成员变量[也叫字段].成员变量的类型可以设置为Java中合法的数据类型,其实成员变量就是普通的变量,可以为它设置初始值,也可以不设置初始值,如果不设 ...
- Java经典书籍-PDF
密码:rhgr https://pan.baidu.com/s/17MkdVFS9JrsbseMveQePOQ
- Centos6.9 安装Oracle11gR2
最近在学习怎么安装Centos,在Centos6.9版本安装Oracle数据库.参考了网络上很多文章,终于可以不报错的完成安装了,在这里记录一下 一.需要用到的安装文件 Centos6.9 ps: ...
- iOS之查看代码运行的时间
有时候我们想要准确的知道某段代码.某个循环执行的时间,然后分析效率等问题,这个时候就需要执行时间是多少.正好看到网上已经有人做了这个工作,我就直接摘下来了.正好也用了宏的方式计算时间,我们只要在需要计 ...
- 【原创】展开二层嵌套列表(或pd.Series)的几种方法效率对比
转载请注明出处:https://www.cnblogs.com/oceanicstar/p/10248763.html ★二层嵌套列表(或以列表为元素的pd.Series)有以下几种展开方式 (1)列 ...
- 【ospf-路由过滤】
- is 和 isinstance的区别 and issubclass
定义一个子类和父类 class A: pass class B(A): pass is print(type(b) is B) # 结果: True print(type(b) is A) # 结果: ...
- mysql-介绍
1.mysql几个重要的文件 每个数据库新建后,会产生数据库文件夹,在该文件夹下每张表均对应以下三个文件: xx.frm 存放表结构 xx.MYD 存放表数据 xx.MYI 存放表索引 mys ...
- MySQL wait_timeout参数修改
MySQL wait_timeout参数修改问题,可能经常会有DBA遇到过,下面就试验一下并看看会有什么现象. wait_timeout分为global级及session级别,如未进行配置,默认值为2 ...