Sticks UVA - 307 剪枝 (超详细的题解)

博客详细解析了UVA 307 Sticks问题,探讨如何通过多种剪枝策略减少计算量,包括枚举范围剪枝、重复木棍剪枝、木棍排序剪枝和起始零长度剪枝。文章提供了问题背景、思路分析及代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Sticks UVA - 307

题目链接
题目大意:有等长木棒,将木棒随意砍成几段,直到每段木棍的长度都不超过50.现在将木棍拼接成原来的样子,但是不记得最开始有多少木棒和它们的分别长度。给出每根小木棍的长度,编程找出原始木棒的最小可能长度。ps:木棒和木棍是不一样的。
思路:这道题非常经典,有多个剪枝,把剪枝用到了极致。
第一个剪枝:我们首先要枚举原来木棒的长度,那么该从几开始,到几结束呢?范围为被截成木棍的最大长度~木棍的长度和/2。而且小木棍总长度一定是大木棒的倍数,单个大木棒不能比最长的小木棍短,如果sum/2已经测试过不合适,(sum/2,sum)这个区间里面的数就不必要尝试了,因为sum不可能是其的倍数。
第二个剪枝:如果当前木棍与前一个木棍相等,并且前一个木棍尝试拼接时没有成功,则不用再验证,直接进行下一个木棍。
第三个剪枝:把小木棍排个序,从大到小开始拼接,因为长木棍拼成木棒所需木棍更少,选择范围小,复杂度较低,深度也更小,也能比较快的判断出该木棒是否能被拼出(从搜索范围较小的开始搜,尽早排除不可能的情况)。也可以想一想:多个较短的小木棒,要比和他们总和等长的的较长的小木棍拼起来更灵活,所以我们先拼接长的,留下小的(也为了后边拼接更方便),若先拼小的,留下长的,可能最后拼不成,还得把前面的拆开。
第四个剪枝:当拼接长度为零时,即从0开始拼接木棒,尝试用当前这个木棍去拼接,但是尝试了所有的木棍都没有拼接成功,即可证明这个木棍无法拼成,直接return 0。
ps:每次遍历小木棒,只需要从上一个拼接位置向后遍历,前面的不用考虑,因为如果前面的能用的话,在之前就已经拼接上了。

当当当~~~
代码如下:

#include<stdio.h>//木棒 木棍不一样
#include<string.h>
#include<algorithm>
using namespace std;
int n,m,sum,k;//m为原始木棒长度,k为原始木棒个数,n为木棍数量
int a[110];
int book[110];
bool cmp(int a,
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值