【搜索】小木棍

【搜索】小木棍

题目描述

乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过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;
}
				
时间: 2024-10-24 08:06:22

【搜索】小木棍的相关文章

P1120 小木棍 [数据加强版]

题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度. 给出每段小木棍的长度,编程帮他找出原始木棍的最小可能长度. 输入输出格式 输入格式: 输入文件共有二行. 第一行为一个单独的整数N表示砍过以后的小木棍的总数,其中N≤65 (管理员注:要把超过50的长度自觉过滤掉,坑了很多人了!) 第二行为N个用空个隔开的正整数,表示N根小木棍的长度. 输出格式: 输出文件仅一行,表示要求

洛谷 P1120 小木棍

题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度. 给出每段小木棍的长度,编程帮他找出原始木棍的最小可能长度. 输入输出格式 输入格式: 输入文件共有二行. 第一行为一个单独的整数N表示砍过以后的小木棍的总数,其中N≤60 (管理员注:要把超过50的长度自觉过滤掉,坑了很多人了!) 第二行为N个用空个隔开的正整数,表示N根小木棍的长度. 输出格式: 输出文件仅一行,表示要求

洛谷P1120 小木棍

洛谷1120 小木棍 题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50.     现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度.     给出每段小木棍的长度,编程帮他找出原始木棍的最小可能长度. 输入输出格式 输入格式: 输入文件共有二行. 第一行为一个单独的整数N表示砍过以后的小木棍的总数,其中N≤60 (管理员注:要把超过50的长度自觉过滤掉,坑了很多人了!) 第二行为N个用空个隔开的正整数,表示N根小木棍的长度.

luogu P1120 小木棍 [数据加强版]

二次联通门 : luogu P1120 小木棍 [数据加强版] /* luogu P1120 小木棍 [数据加强版] 暴搜 + 剪枝 枚举可能的长度 挨个检查答案 二分显然正确性不能保障 搜索时从最大的开始找 放上当前木棍后的长度比枚举的长度要大, 则退出 若当前的长度与当前扫到的木棍长度相同, 或是还需要的长度与枚举的长度相同,则退出 若当前的木棍不符合要求, 则后面与它长度相同的木棍都不行 */ #include <algorithm> #include <iostream>

小木棍(爆搜减枝)

题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过5050. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度. 给出每段小木棍的长度,编程帮他找出原始木棍的最小可能长度. 输入输出格式 输入格式: 共二行. 第一行为一个单独的整数N表示砍过以后的小木棍的总数,其中N≤65N≤65 (管理员注:要把超过5050的长度自觉过滤掉,坑了很多人了!) 第二行为NN个用空个隔开的正整数,表示NN根小木棍的长度. 输出格式: 一个数,表示要

1442:【例题3】小木棍

1442:[例题3]小木棍 题解 从最优性方面: 1.设所有木棍长度和为maxn,那么原长度(也就是需要输出的长度)一定能够被maxn整除,这样得到的木棍根数才是整数2.木棍原来的长度一定不小于所有木棍中最长的那根综上两点,可以确定原木棍的长度len在最长木棍的长度minx和maxn之间取值,且maxn能被len整除.所以在搜索原木棍的长度时,可以从砍过以后所有木棍中最长的长度开始,每次增加长度后,必须能整除maxn.这样可以有效优化程序. 从可行性方面: 1.短木棍更加灵活,长木棍受到的限制更

P1120小木棍

题目传送P1120 有许多剪枝的搜索 先考虑答案的范围,先把小木棍排个序,原木棍的长一定大于等于最长的一根 然后,就枚举一下原木棍的长度,搜是否能按这个长度拼成所有的木棍,如果能拼成直接就是答案了 确定了原始长度,然后用总长度就能算出原始木棍的条数.如果不能整除的话,肯定不是答案 然后确定搜索的状态,当前拼到第几跟,这一根还剩多长,拼这一根用的上一根小木棍的编号 我们肯定要先拼大的,再用小的去补大的 如果我们用小的凑的话,那些大的很难凑齐 还有一个优化就是,有很多长度相同的小木棍,对于一种长度不

P1120 小木棍 [数据加强版] 题解

原题链接 简要题意: 把若干 \(\leq 50\) 的小木棍拼成若干长度相同的长木棍(一个小木棍也可以作为一根长木棍).求可以拼成的长木棍的最小长度. 暴力出奇迹 一看数据范围,\(n \leq 65\). 这一看就是指数级复杂度 我还没见过什么 \(O(n^5)\) 的算法.. 首先考虑 \(\texttt{dfs}\),枚举长木棍的长度,然后用 \(\texttt{dfs}\) 进行暴力枚举当前的小木棍分给哪一组(可以算出组数的),验证即可. 对这种最 卑劣 不太行的搜索,下面开始大力剪枝

洛谷P1120小木棍[DFS]

题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度. 给出每段小木棍的长度,编程帮他找出原始木棍的最小可能长度. 输入输出格式 输入格式: 输入文件共有二行. 第一行为一个单独的整数N表示砍过以后的小木棍的总数,其中N≤60 (管理员注:要把超过50的长度自觉过滤掉,坑了很多人了!) 第二行为N个用空个隔开的正整数,表示N根小木棍的长度. 输出格式: 输出文件仅一行,表示要求