题目描述

pdf

题解

注意的问题是,各个原始木棒的长度都是一样的!

说一下本题的总思路即:DFS+超强力剪枝!(详见本人的 AC 程序)

首先,我们要从小到大枚举原始木棒的长度len,也就是枚举答案,最先找到的就是最小长度。那怎么确定枚举的是正确的呢?我们用的是搜索。

如果只搜索是极不理智的,而如果有了剪枝,一切就好说了,本题的剪枝主要有五个,我们会边看程序边了解一下。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int len,n;
bool v[];
int a[];
int cnt,sum,val;
//stick 即正在拼第stick根木棒(确保前面的都拼好了)
//第stick根木棒的当前长度为cab
//拼第stick根木棒的上一根小木棒为last(有些小朋友可能会有疑问,为什么第一次搜索是dfs(1,0,1)而不是dfs(1,0,0)首先,如果dfs(1,0,0)也能过并且更正确一些,而即使dfs(1,0,1)在bfs中的第三个if中,因为v[i]==1也不会进入)
bool dfs(int stick,int cab,int last)
{
if(stick>cnt)
return true;//所有的木棒都已经拼好
if(cab==len)
return dfs(stick+,,); //当前的一根已经拼好,开始下一根
int fail=;//第二个剪枝开始了:对于每根木棒,fail记录的是最近一次尝试拼接的木棍长度。这样再回溯时就不会再尝试相同长度的木棍。
for(int i=last;i<=n;i++)//第三个剪枝开始了:限制先后加入一根原始木棍的长度是递减的。因为先拼上一个长为x的木棍再拼上一个长为y的木棍,等效于先拼上一个长为y的木棍再拼上一个长为x的木棍。所以只需要搜索其中一种即可。
{
if(v[i]==&&a[i]+cab<=len&&fail!=a[i])
{
v[i]=;
if(dfs(stick,cab+a[i],i))
return true;
v[i]=;//还原搜索前的状态。
fail=a[i];
if(cab==||cab+a[i]==len)
return false;//第四个剪枝开始了:如果在一根原始木棒中尝试拼接的第一根木棍的递归分支就以失败返回,直接判断当前分支无解。与此同时,第五个剪枝开始了,如果两个木棍的长度和与一个木棍的一样,只尝试一个的就行了(因为前两个可能会有更大的效用)
}
}
return false;//所有分支都尝试过,搜索失败。
}
int main()
{
while(cin>>n&&n)
{
sum=;
val=;
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
sum+=a[i];//为啥要累加尼?为了求原始木棒的根数,即sum/len(len是枚举的答案)
val=max(val,a[i]);
}
sort(a+,a+n+);//第一个剪枝开始了:此为优化搜索顺序,优先尝试较长的木棍
reverse(a+,a+n+);//sort从小到大排序,而reverse会将整个数组翻转(懒人做法),这样就可以达到从大到小排的结果
for(len=val;len<=sum;len++)
{
if(sum%len)
continue;
cnt=sum/len;
memset(v,,sizeof(v));
if(dfs(,,))//(1,0,1具体是啥,看上方的dfs)
{
cout<<len<<endl;
break;//确定枚举正确的第一次即为答案,立即结束
}
}
}
return ;
}

数据下载

P1120/UVA307 小木棍(sticks) 题解的更多相关文章

  1. [UVA307]小木棍 Sticks

    题目大意:有一堆小木棍,把它们接成相同长度的小木棍,问结果的小木棍的最小长度是多少,多组数据 题解:$dfs$,各种剪枝. 卡点:无 C++ Code: #include <cstdio> ...

  2. 【洛谷UVA307】小木棍Sticks

    小木棍Sticks[传送门] 算法的话:dfs+超强剪枝: (另外注意UVA上好像不接受万能头[因为万能头WA了两次,瑟瑟发抖]) 思路: 最直接的思路,枚举木棍长度来dfs,但这样很容易就TLE了. ...

  3. 题解 P1120 【小木棍 [数据加强版]】

    题面 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度. 给出每段小木棍的长度,编程帮 ...

  4. 【Luogu P1120】小木棍

    题目: 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过$50$.现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度.给出每段小木棍的长度,编程 ...

  5. 【题解】洛谷P1120 小木棍(搜索+剪枝+卡常)

    洛谷P1120:https://www.luogu.org/problemnew/show/P1120 思路 明显是搜索题嘛 但是这数据增强不是一星半点呐 我们需要N多的剪枝 PS:需要先删去超出50 ...

  6. 题解0007:小木棍(P1120)

    (错误记录) 题目链接:https://www.luogu.com.cn/problem/P1120 题目描述:几根同样长的木棍,小冥把它们随意砍成了n段: 然后他又吃饱了撑的想把木棍拼上: 但是这个 ...

  7. 洛谷P1120 小木棍(sticks数据加强版)

    题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度. 给出每段小木棍的长度,编 ...

  8. 一本通&&洛谷——P1120 小木棍 [数据加强版]——题解

    题目传送 一道特别毒瘤能提醒人不要忘记剪枝的题. 首先不要忘了管理员的话.忘把长度大于50的木棍过滤掉真的坑了不少人(包括我). 显然是一道DFS题 .考虑剪枝. 找找搜索要面临的维度.状态:原始木棍 ...

  9. 洛谷 P1120 小木棍 [数据加强版]解题报告

    P1120 小木棍 [数据加强版] 题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它 ...

随机推荐

  1. 红帽RHCE培训-课程2笔记内容

    1 kickstart自动安装 已安装系统中,在root下述目录会自动生成kickstart配置文件 ll ~/anaconda-ks.cfg 关键配置元素注释,详见未精简版 创建Kickstart配 ...

  2. buuctf Easysql 小记

    堆叠注入 利用原理: 补充系统变量@@sql_modesql_mode:是一组mysql支持的基本语法及校验规则PIPES_AS_CONCAT:将“||”视为字符串的连接操作符而非或运算符,这和Ora ...

  3. 攻防世界 robots题

    来自攻防世界 robots [原理] robots.txt是搜索引擎中访问网站的时候要查看的第一个文件.当一个搜索蜘蛛访问一个站点时,它会首先检查该站点根目录下是否存在robots.txt,如果存在, ...

  4. 【C语言】无参函数调用实例

    #include<stdio.h> void hello() { printf("年轻人,加油!"); } int main() { hello(); ; }

  5. 洛谷 P2239 螺旋矩阵(模拟 && 数学)

    嗯... 题目链接:https://www.luogu.org/problem/P2239 这道题首先不能暴力建图,没有简单方法,只有进行进行找规律. AC代码: #include<cstdio ...

  6. mysql中的数据类型长度

    “mysql中的数据类型长度是固定的 数据类型后面改的只是展示长度 没用的 int就是四个字节 2的31次方减一是最大值 所以改这个长度没用 只能改数据类型”

  7. //C语言:将一个由字符0和1组成的表示二进制数的字符串,转换成相应的十进制数返回。

    //函数fun:将一个由字符0和1组成的表示二进制数的字符串,转换成相应的十进制数返回. #include <stdio.h> #pragma warning (disable:4996) ...

  8. How2j学习java-3下载 ECLIPSE

    1.下载并解压Eclipse 下载并解压到e:/eclipse,目录情况如图所示.注: 这个Eclipse是64位的,应该使用本站提供的JDK(64)位,下载地址:JDK. 如果JDK位数和 Ecli ...

  9. C语言笔记 11_头文件&强制类型转换&错误处理&递归

    头文件 头文件是扩展名为 .h 的文件,包含了 C 函数声明和宏定义,被多个源文件中引用共享.有两种类型的头文件:程序员编写的头文件和编译器自带的头文件. 在程序中要使用头文件,需要使用 C 预处理指 ...

  10. 基于soa的架构

    SOA:Service Oriented Architecture面向服务的架构.也就是把工程拆分成服务层.表现层两个工程.服务层中包含业务逻辑,只需要对外提供服务即可.表现层只需要处理和页面的交互, ...