第一次遇到的时候,这个题目完全没思路,看了人家的解题报告才做,,也不行,各种TLE。。也没什么想法。。只能借鉴别人的了。。

看完这个应该可以彻底的理解这个题目的。。:http://apps.hi.baidu.com/share/detail/17119728

下面是我的代码:

#include<iostream>
#include<stdlib.h>
#include <string.h>
using namespace std;

#define N 70
int sticks[N];//用来存放木棒的长度
int used[N];//用来记录木棒是否使用过
int n,cnt,m,len,flag;

int cmp(const void *a,const void *b)
{
    return *(int *)b-*(int *)a;
}

void dfs(int pos,int current,int cnt)//pos用来记录当前sticks[]数组中比较到哪个地方了,current用来记录当前匹配的木棒的长度,cnt记录以匹配的木棒的数量
{
    
    if(cnt==m)
        flag=true;//如果以当前的长度能正好匹配完所有的木棒的时候则返回,完成任务,当前长度就是要匹配的最小长度
    else if(current==len)//如果current正好等于len,则完成一次匹配,cnt+1;
        dfs(0,0,cnt+1);
    else
    {
        int pre=-1;//记录前一个搜索过的值,此次匹配过程中已经搜索过的数值,相同长度就的就不必再匹配
        for(int i=pos;i<n;i++)
        {
            if(!used[i]&&sticks[i]!=pre&&current+sticks[i]<=len)//很重要的剪枝条件,不容忽略,剪枝的技巧和艺术
            {
                used[i]=1;
                pre=sticks[i];
                dfs(pos+1,current+sticks[i],cnt);
                used[i]=0;//此次搜索不成功,恢复使用标志
                if(pos==0||flag)//只有一根木棒或者已经搜索成功时返回
                    return ;
            }
        }
    }
}

int main()
{
    while(cin>>n&&n>0)
    {
        int sum=0;
        for(int i=0;i<n;i++)
        {
            cin>>sticks[i];
            sum+=sticks[i];
        }
        memset(used,0,sizeof(used));
        qsort(sticks,n,sizeof(sticks[0]),cmp);//木棒长度按照从大到小的长度排序,按照题目的意思,原始木棒的最小长度至少是被截断后最长的木棒的长度,最大是被截后所有木棒的长度和
        flag=false;//标志是否成功
        for(len=sticks[0];len<=sum;len++)//从原始木棒可能的长度逐一搜索,一旦成功就停止循环,得到的就是最小的
        {
            if(sum%len==0)//一个很重要的剪枝条件,不容忽略,可以很大的提高效率
            {
                m=sum/len;
                dfs(0,0,0);
                if(flag)
                    break;
            }
        }
        cout<<len<<endl;
    }
    return 0;
}

posted on 2012-02-10 17:06  →木头←  阅读(400)  评论(0编辑  收藏  举报