poj1011

题意:一些木棍,已知每个的长度,把他们全用上,去拼成一些长度相等的木棍,最小长度是多少。

分析:dfs。先计算所有木棒的长度之和,然后枚举每个能被整除这个和的长度作为结果,并递归判断是否可行。

递归过程需要加一些优化:

1.先把木棍从大到小排序,大木棍的灵活性低,较难满足,因此先判断。

2.在拼一个木棍时所使用的第一个小木棍如果不行,那么当前大木棍的长度可以被舍弃。

#include <iostream>
#include <algorithm>
using namespace std;

const    int        maxn = 64;

int        t, n, stick[maxn], each, ok, total, num;
bool    used[maxn];


void init()
{
    int        i;

    total = 0;
    for (i = 0; i < n; i++)
    {
        scanf("%d", &stick[i]);
        total += stick[i];
    }
    ok = false;
    memset(used, 0, sizeof(used));
}

void dfs(int length, int start)
{
    int        i;

    if (ok)
        return;
    if (length >= total)
    {
        ok = true;
        return;
    }
    if (length % each == 0)
    {
        i = start;
        while (used[i])
            i++;
        used[i] = true;
        dfs(length + stick[i], i + 1);
        used[i] = false;
        return;
    }
    for (i = start; i < n; i++)
    {
        if (used[i])
            continue;
        if (stick[i] + length < length / each * each + each)
        {
            used[i] = true;
            dfs(length + stick[i], i + 1);
            used[i] = false;
            if (ok)
                return;
        }else if (stick[i] + length == length / each * each + each)
        {
            used[i] = true;
            dfs(length + stick[i], 0);
            used[i] = false;
            return;
        }
    }
}

int main()
{
    int        i, t, ans;

    //freopen("t.txt", "r", stdin);
    while (cin >> n && n != 0)
    {
        init();
        sort(stick, stick + n);
        for (i = 0; i < n / 2; i++)
        {
            t = stick[i];
            stick[i] = stick[n - i - 1];
            stick[n - i - 1] = t;
        }
        for (i = stick[0]; i < total; i++)
            if (total % i ==0)
            {
                each = i;
                num = total / i;
                dfs(0, 0);
                if (ok)
                {
                    ans = each;                
                    break;
                }
            }
        if (!ok)
            ans = total;
        cout << ans << endl;
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/rainydays/p/3203953.html