题解 Sticks 小木棍

简介: 这篇文章提供了一个C++程序的题解,使用深度优先搜索(DFS)和剪枝技术来解决如何将不同长度的小木棍拼接成若干根长度相等的木棍的问题,以求得拼接长度的最小值。

题解 Sticks 小木棍

题目描述: 每组数据给出N根小木棍,把它们拼接成若干根长度相等的木棍,求该长度的最小值。

题解:

该题就是dfs深搜+剪枝


```cpp
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int arr[68],book[68];
int len,n;
int cnt,sum,flag; //
void dfs(int stick,int cab,int last)
{

 if(stick==cnt){cout<<sum/cnt<<endl;flag=1;return;}
 if(flag==1)return;
    if(cab==len)
    {
       dfs(stick+1,0,1);
        return;
    }
    int fail=0; //剪枝(1),剪掉插入相同长度的木棍这一情况
    for(int i=last;i<=n;i++)//剪枝(2),i=last 前面的木棍一定插过了,用这个来剪掉无谓的循环部分
    {

        if(book[i]||arr[i]+cab>len||fail==arr[i])continue;

            book[i]=1;
            dfs(stick,cab+arr[i],i);
            book[i]=0;
            fail=arr[i];
           if(cab==0||cab+arr[i]==len)return;  //剪枝(3),如果此时为拼成长度为零或者刚好拼成却还得回溯,那么说明这一步怎么怎么插入都错,所以直接回溯
    }
}
bool cmd(int a,int b){return a>b;} //剪枝(4)降序排序减少查找次数
int main()
{
    int t;
   while(cin>>n&&n)
   {

       sum=0;
       int maxn=0;
        flag=0;
        for(int i=1;i<=n;i++)cin>>arr[i],sum+=arr[i],maxn=max(maxn,arr[i]);//剪枝(5),组成木棍最小为maxn,所以直接从maxn开始
        sort(arr+1,arr+n+1,cmd);
        for(len=maxn;len<=sum;len++)
        {
            if(sum%len||flag)continue;
            memset(book,0,sizeof(book));
            cnt=sum/len;
            dfs(0,0,1);
        }
   }
    return 0;

}
相关文章
|
2月前
【LeetCode 17】5.7四数之和
【LeetCode 17】5.7四数之和
34 1
|
4月前
|
算法
LeetCode第18题四数之和
该文章介绍了 LeetCode 第 18 题四数之和的解法,与三数之和类似,通过先排序,再用双指针确定坐标并去重的方式解决,关键是确定四个坐标,前两个通过两层循环确定,后两个通过首尾双指针确定,同时总结了双指针可减少循环次数,使解决方式更简单高效。
LeetCode第18题四数之和
|
7月前
[leetcode] 四数之和 M
[leetcode] 四数之和 M
|
7月前
|
Java 测试技术 C++
leetcode-18:四数之和
leetcode-18:四数之和
47 0
|
7月前
|
Java
leetcode-53:最大子序和
leetcode-53:最大子序和
41 0
|
算法 安全 Swift
LeetCode - #18 四数之和
不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。
leetcode:18.四数之和
这题和前面的一道三数之和类似,解题的思路都一样,这里直接选取两个基准就可以了,然后循环出所有的组合进行判断,如果正好相等那么就加入Set集合中。
62 0
LeetCode 376. Wiggle Subsequence
如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为摆动序列。第一个差(如果存在的话)可能是正数或负数。少于两个元素的序列也是摆动序列。
100 0
LeetCode 376. Wiggle Subsequence
|
索引
LeetCode 392. Is Subsequence
给定字符串 s 和 t ,判断 s 是否为 t 的子序列。 你可以认为 s 和 t 中仅包含英文小写字母。字符串 t 可能会很长(长度 ~= 500,000),而 s 是个短字符串(长度 <=100)。 字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"是"abcde"的一个子序列,而"aec"不是)。
106 0
LeetCode 392. Is Subsequence