hdu 1455 DFS+剪枝

/*
题意:给出一堆小木棍,将这些木棍拼接成长度相等的若干条木棍,问可以拼接出来的最短的长度。

题解:DFS+剪枝
*/
#include <iostream>
#include <algorithm>
#include <cstdio>

using namespace std;

int s[70];
int a,n,sum;
bool f[70];

bool cmp(int a, int b)
{
    return a>b;
}

//ans记录当前拼了的木棍总长度,as表示当前拼接的那根木棍的长度,j表示从第j个棍开始搜索
bool dfs(int ans, int as, int j)
{
    if (ans == sum)
        return true;
    for(int i=j; i<n; i++)
        if (!f[i] && as+s[i]<=a)
        {
            if (as+s[i] == a)
            {
                f[i] = true;
                if (dfs(ans+s[i],0, 0))
                    return true;
                f[i] = false;
                if (as == 0)//当as为0而前面的dfs没有返回true,说明当前的拼法是错误的,返回false
                    return false;
            }
            else
            {
                f[i] = true;
                if (dfs(ans+s[i],as+s[i], i+1))
                    return true;
                f[i] = false;
                if (as == 0)
                    return false;
            }
        }
    return false;
}

int main(void)
{
    while (cin >> n && n)
    {
        sum = 0;//sum记录木棍总长度
        for(int i=0; i<n; i++)
        {
            cin >> s[i];
            sum += s[i];
        }
        sort(s,s+n,cmp);//从大到小排序
        for(a=s[0]; a<=sum; a++)// 从最长的木棍开始
        {
            if (sum%a == 0)//因为是等长木棍,因此需要sum的约数才可能正确
            {
                memset(f,false,sizeof(f));
                if (dfs(0,0,0))
                {
                    cout << a << endl;
                    break;
                }
            }
        }
    }
    return 0;
}

 

posted @ 2014-03-20 23:30  辛力啤  阅读(176)  评论(0编辑  收藏  举报