一、题目回顾

题目链接: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的更多相关文章

  1. DFS(深度优先)算法编程实践

    DFS定义 DFS(Depth-First-Search)深度优先搜索算法,是搜索算法的一种.是一种在开发爬虫早期使用较多的方法.它的目的是要达到被搜索结构的叶结点 . 特点 每次深度优先搜索的结果必 ...

  2. 拓扑排序+DFS(POJ1270)

    [日后练手](非解题) 拓扑排序+DFS(POJ1270) #include<stdio.h> #include<iostream> #include<cstdio> ...

  3. DFS(一):深度优先搜索的基本思想

    采用搜索算法解决问题时,需要构造一个表明状态特征和不同状态之间关系的数据结构,这种数据结构称为结点.不同的问题需要用不同的数据结构描述. 根据搜索问题所给定的条件,从一个结点出发,可以生成一个或多个新 ...

  4. 深度优先搜索DFS(一)

      实例一  0/1背包问题:   有n件物品,每件物品的重量为w[i],价值为c[i].现在需要选出若干件物品放入一个容量为V的背包中,使得在选入背包的物品重量和不超过容量V的前提下,让背包中的物品 ...

  5. 万能的搜索--之DFS(二)

    (一)深度优先搜索(DFS) 我们先给出深度优先的解决办法,所谓深度优先搜索,在迷宫问题里就是不撞南墙不回头,能走得深一点就尽量深一点.如果碰到了墙壁就返回前一个位置尝试其他的方向.在<啊哈!算 ...

  6. DFS(二):骑士游历问题

    在国际象棋的棋盘(8行×8列)上放置一个马,按照“马走日字”的规则,马要遍历棋盘,即到达棋盘上的每一格,并且每格只到达一次.例如,下图给出了骑士从坐标(1,5)出发,游历棋盘的一种可能情况. [例1] ...

  7. DFS(四):剪枝策略

    顾名思义,剪枝就是通过一些判断,剪掉搜索树上不必要的子树.在采用DFS算法搜索时,有时候我们会发现某个结点对应的子树的状态都不是我们要的结果,这时候我们没必要对这个分支进行搜索,砍掉这个子树,就是剪枝 ...

  8. DFS(三):八皇后问题

    [例1]八皇后问题. 在一个8×8国际象棋盘上,放置8个皇后,每个皇后占一格,要求皇后间不会出现相互“攻击”的现象,即不能有两个皇后处在同一行.同一列或同一对角线上.问共有多少种不同的放置方法? (1 ...

  9. 【递归入门】组合+判断素数:dfs(递归)

    题目描述 已知 n 个整数b1,b2,…,bn,以及一个整数 k(k<n).从 n 个整数中任选 k 个整数相加,可分别得到一系列的和. 例如当 n=4,k=3,4 个整数分别为 3,7,12, ...

随机推荐

  1. LeetCode8.字符串转换整数(atoi) JavaScript

    请你来实现一个 atoi 函数,使其能将字符串转换成整数. 首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止. 当我们寻找到的第一个非空字符为正或者负号时,则将该符号与之 ...

  2. Python 学习笔记(七)Python字符串(二)

    索引和切片 索引  是从0开始计数:当索引值为负数时,表示从最后一个元素(从右到左)开始计数 切片 用于截取某个范围内的元素,通过:来指定起始区间(左闭右开区间,包含左侧索引值对应的元素,但不包含右测 ...

  3. 菜鸟笔记 -- Chapter 6.1 面向对象概述

    6.1 面向对象概述 在程序开发的初期人们使用结构化开发语言,但是随着时间的流逝,软件的规模越来越庞大,结构化语言的弊端逐渐暴露出来,开发周期被无限制拖延,产品质量也不尽如人意,人们终于发现结构化语言 ...

  4. git使用简介(二)

    附上廖雪峰老师Git教程https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000 远程仓库 ...

  5. vue、html与iframe html事件相互调用

    一.html文件中引入的iframe标签 1.在父html中调用子iframe html 中的事件 通过contentwindow属性 document.getElementById("my ...

  6. POJ 2007--Scrambled Polygon(计算凸包,点集顺序)

    Scrambled Polygon Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 10094   Accepted: 476 ...

  7. node-zookeeper-dubbo 和egg实现远程连接

    基于js的node-zookeeper-dubbo 和egg实现远程连接服务 const nzd = require('node-zookeeper-dubbo'); const opt={ appl ...

  8. hibernate的CRUD操作

    一对多关系映射的crud操作: 1.单项的保存操作 /** * 保存操作 * 正常的保存:创建一个联系人,需要关联客户 */ @Test public void test1(){ Session s= ...

  9. dedecms左侧导航栏不显示问题

    dedecms左侧导航栏不显示问题 在做织梦项目时,经常会碰到后台左侧导航栏不显示的问题,如下所示: ​ 这主要是由于文件权限不足造成的.有两种方法 第一种:把 /data 文件夹全部改成 777 权 ...

  10. ruby 数据类型String

    一.字符串创建 单引号包含,不支持转义符和内嵌表达式#{}(插值符) str = 'hello world!' 双引号包含 str = "hello world!" 使用%,%Q, ...