码迷,mamicode.com
首页 > 其他好文 > 详细

小木棍

时间:2019-09-30 12:48:43      阅读:97      评论:0      收藏:0      [点我收藏+]

标签:memset   大于   sum   找不到   开始   顺序   性方面   line   可行性   

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("\n");*/
//    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;
}

 

小木棍

标签:memset   大于   sum   找不到   开始   顺序   性方面   line   可行性   

原文地址:https://www.cnblogs.com/fangbozhen/p/11612028.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!