小木棍

Posted fangbozhen

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了小木棍相关的知识,希望对你有一定的参考价值。

https://loj.ac/problem/10020

题目描述

  有N根小木棍,他们有各自的长度,若它们能拼成整数多的len长的木棍,求len的最小值。

思路

  从题目上看,一个显然的思路是我们可以暴力从小到大枚举len,用dfs看能否拼成这么多木棍。不过裸的dfs肯定T飞了,我们尝试进行优化。

    首先从可行性方面进行优化,我们提出五种剪枝:

    ①一根长木棍用处肯定比用几根短木棍拼成相同长度的作用小,所以我们可以把木棍从大到小排序。

    ②我们按照这个顺序依次处理每一根木棍,那么显然到第i个木棍时,只能从i+1开始寻找,因为前面的都已用过。

    ③相同长度的木棍不用搜索多次,可以直接处理。对于找不到时可直接返回。

    ④判断当前木棍的长度能否拼成len长木棍,不能就直接返回。

    ⑤找到答案立刻返回。

    我们再从最优性方面做出两种剪枝:

    ⑥设所有木棍长为sum,那我们枚举的len一定能被len整除。

    ⑦len一定大于等于剩余木棍中最长的。

代码

#include <bits/stdc++.h>
using namespace std;
int m,n,len,used[70],a[70];
bool f;
bool cmp(int x,int y)
{
    return x>y;
}
void dfs(int k,int last,int rest)
{
    int i;
    if(f)return ;                        //剪枝⑤ 
//    cout<<k<<‘ ‘<<rest<<endl; 
    if(k==m){f=1;return ;}
    if(rest==0)
    {
        for(i=1;i<=n;i++)
            if(!used[i])break ;
        used[i]=1;
        dfs(k+1,i,len-a[i]);
        used[i]=0;
    }
    for(i=last+1;i<=n;i++)                //剪枝② 
        if(!used[i]&&a[i]<=rest)         
        {
            used[i]=1;
            dfs(k,i,rest-a[i]);
            used[i]=0;
            int j=i;
            while(i<n&&a[i]==a[j])i++;  //剪枝③ 
            if(i==n)return ;
        }
}
int main() 
{
    int sum=0,minn=0;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        sum+=a[i];
        minn=max(a[i],minn);
//        cout<<minn<<endl;
    }
    sort(a+1,a+n+1,cmp);                //剪枝① 
/*    for(int i=1;i<=n;i++)
        printf("%d ",a[i]);
    printf("
");*/
//    cout<<sum<<endl;
    for(int i=minn;i<=sum;i++)          //剪枝⑥ 
        if(sum%i==0)                    //剪枝⑤ 
        {
//            cout<<i<<endl;
            memset(used,0,sizeof(used));
            f=0;used[1]=1;
            len=i;m=sum/i;
            dfs(1,1,len-a[1]);
            if(f){printf("%d",i);break ;}
        }
    return 0;
}

 

以上是关于小木棍的主要内容,如果未能解决你的问题,请参考以下文章

小木棍 [数据加强版]

小木棍(爆搜减枝)

小木棍 [数据加强版]

洛谷P1120 小木棍 [数据加强版]

1442:例题3小木棍

洛谷 P1120 小木棍