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

【搜索】小木棍

时间:2016-08-06 20:23:26      阅读:176      评论:0      收藏:0      [点我收藏+]

标签:

【搜索】小木棍

题目描述

乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50。

现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度。

给出每段小木棍的长度,编程帮他找出原始木棍的最小可能长度。

输入

共有二行。
第一行为一个单独的整数N表示看过以后的小木柜的总数,其中N≤60,第二行为N个用空个隔开的正整数,表示N跟小木棍的长度。

输出

仅一行,表示要求的原始木棍的最小可能长度。

样例输入

9
5 2 1 5 2 1 5 2 1

样例输出

6
枚举并判断max(a[0……n-1])~sum(a[0]+a[1]+……+a[n-1])之间的长度l并且 sum%l == 0
如果能够组成num个小木棍, 并且num == sum/l就成功了
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <queue>

using namespace std;

const int MAXN = 63;
int a[MAXN], n, sum, m, aim, b[MAXN];
bool slove(int i, int len, int num) {
    if(i == n && num == sum / aim) {
        return true;
    }
    if(i == n) return false;
    for(int j = 0; j < n; j++) {
        if(!b[j]) {
            if(a[j] + len == aim) {
                b[j] = true;
                slove(i+1, 0, num+1);
                b[j] = false;
            }
            if(a[j] + len < aim) {
                b[i] =  true;
                slove(i+1, len + a[j], num);
                b[j] = false;
            }
        }

    }
}
int main() {
    scanf("%d", &n);
    sum = m = 0;
    for(int i = 0; i < n; i++) {
        scanf("%d", &a[i]);
        sum += a[i];
        m =  max(m, a[i]);
    }
    for(aim = m; aim <= sum; aim++) {
        if(sum % aim == 0) {
            memset(b, false, sizeof(b));
            if(slove(0, 0, 0)) {
                printf("%d\n", aim);
                break;
            }

        }
    }
    return 0;
}

 


【搜索】小木棍

标签:

原文地址:http://www.cnblogs.com/cshg/p/5744667.html

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