【搜索】小木棍
题目描述
乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过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