zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    .Net中多线程类的使用和总结
    单例模式完整解析
    避免构造/析构函数调用虚函数(转)
    正则表达式
    序列化与反序列化
    数组的使用,指针的使用
    jmeter单接口和多接口测试
    HTML5 input placeholder 颜色修改
    h5动画效果总结
    8月份月度反思--做一个快乐的程序员
  • 原文地址:https://www.cnblogs.com/rainydays/p/3203953.html
Copyright © 2011-2022 走看看