牛客

链接:https://ac.nowcoder.com/acm/problem/50243
来源:牛客网

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld

题目描述

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

输入描述:

第一行为一个单独的整数N表示砍过以后的小木棍的总数。第二行为N个用空格隔开的正整数,表示N根小木棍的长度。

输出描述:

输出仅一行,表示要求的原始木棍的最小可能长度。
示例1
输入
9
5 2 1 5 2 1 5 2 1
输出
6
备注:
1<=N<=60

题目大意:
给出n个小木棍,你的任务是把他们拼接起来,还原原来的木棍,求拼接后每个小木棍的最小长度。

解题思路:
这个题注意一定要用搜索做而不是二分,之前做过一个拆分木棍的题是二分,因为那个题长度和拆分的数量有一个线性关系,而这个合并木棍并没有,我们用DFS+剪枝AC这个题,因为要求最小的长度,我们先将木棍排序,因为要求拼成的最小的长度,我们要从这些木棍最长的开始往上枚举,对每一个枚举的长度进行搜索,搜索的状态是(剩余木棍的个数,枚举的长度,当前拼成木棍剩余长度,和当前枚举的哪一根木棍)另外需要剪枝操作,剪枝有以下几点:

  1. 如果当前木棍是当去拼枚举长度的第一根,则需要剪掉,因为我们从最长的开始枚举,如果连第一个都拼不上,那么后面的肯定也拼不上。
  2. 如果当前木棍是当去拼枚举长度的最后一根,也需要剪掉,因为木棍是从大到小排,如果这个长度都不行,那后面的长度肯定比这个还小,肯定也拼不上,剪掉。
  3. 如果当前小木棍拼不上,那么和当前木棍长度相同的木棍肯定也拼不上,直接过滤掉和当前木棍长度相等的木棍即可。

AC代码:

#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 65;
int a[N],n;
bool vis[N];
bool cmp(int a,int b) { return a>b; }
bool dfs(int num,int len,int rest,int now)
{
    if(num==0&&rest==0)//当前剩余0个木棍且当前要拼的长度为0时代表可以拼成
      return true;
    if(rest==0)
      rest=len,now=0;
    for(int i=now;i<n;i++)
    {
        if(a[i]>rest)
          continue;
        if(!vis[i])
        {
            vis[i]=true;
            if(dfs(num-1,len,rest-a[i],i+1))
              return true;
            vis[i]=false;
            if(a[i]==rest||len==rest)//第一个木棍和最后一个木棍的时候剪掉
              break;
            while(a[i]==a[i+1])//过滤掉相同的木棍
              i++;
        }
    }
    return false;
}
int main()
{
    int sum=0,s=0;
    scanf("%d",&n);
    memset(vis,false,sizeof vis);
    for(int i=0;i<n;i++)
    {
        scanf("%d",&a[i]);
        if(a[i]<=50)
          sum+=a[i];
        else
          s++;  
    }
    n-=s;
    sort(a,a+n,cmp);
    for(int i=a[0];i<=sum;i++)//从最大的开始枚举
    {
        if(sum%i==0)
          if(dfs(n,i,0,0))
          {
              printf("%d
",i);
              break;
          }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/Hayasaka/p/14294259.html