Sticks
Sticks |
George took sticks of the same length and cut them randomly until all partsbecame at most 50 unitslong. Now he wants to return sticks to the original state, but he forgothow many sticks he had originally andhow long they were originally. Please help him and design a program whichcomputes the smallest possibleoriginal length of those sticks. All lengths expressed in units are integersgreater than zero.
Input
The input file contains blocks of 2 lines. The first line contains thenumber of sticks parts after cutting.The second line contains the lengths of those parts separated by thespace. The last line of the file contains zero.
Output
The output file contains the smallest possible length of original sticks,one per line.
Sample Input
9 5 2 1 5 2 1 5 2 1 4 1 2 3 4 0
Sample Output
6 5 题意: 找出一个最短长度, 使得N个棒子以任意数目组合, 正好用完这些棒子, 每一组长度都是这个最短长度 例如 第一个样例 5+1 5+1 5+1 2+2+2 都是等于6 所以答案是6 搞清楚题意就想做法: 这题有很多需要剪枝的地方(代码中有标识) 另外需要先对小木棍排序, 从大到小 因为假如是1 2 3 4这样的数据, 那么组成全部长度都为1的木棍是没有可能的, 应该最小从4开始组合 另外如果1 2 3 4的总长度是10, 那么如果组成长度为5的木棍失败, 那么去组6是不可能了, 因为剩下的长度是4, 这是矛盾 所以搜索区间应该是[小棍中最长的一根长度, 总长度的一半] 我的代码只在POJ上通过, 在UVA上没过...Runtime error... 大家可以帮我找找哪里还可以剪枝 POJ AC代码#include<stdio.h> #include<algorithm> #include<stdlib.h> using namespace std; int n; int cmp(int a, int b) { return a > b; } int DFS(int *stack, int curlen, int aimlen, int sta, int *vis, int num) { if(num == n) return 1; int same = -1; for(int i = sta; i < n; i++) { if(vis[i] || stack[i] == same) //剪二:判断是否用过此小枝, 且相同长度的小枝不重复用 continue; vis[i] = 1; if(curlen + stack[i] < aimlen) { if(DFS(stack, curlen + stack[i], aimlen, i, vis, num+1)) return 1; else same = stack[i]; } else if(curlen + stack[i] == aimlen) { if(DFS(stack, 0, aimlen, 0, vis, num+1)) return 1; else same = stack[i]; } vis[i] = 0; if(curlen == 0) //剪三:如果第一个棒子都没的组, 长度还是0, 那么不用再找, 已经行不通了 break; } return 0; } int main() { while(scanf("%d", &n) && n) { int sumlen = 0; int *stack = new int[n]; int *vis = new int[n]; for(int i = 0; i < n; i++) { scanf("%d", &stack[i]); sumlen += stack[i]; vis[i] = 0; } int flag = 1; sort(stack, stack + n, cmp); int maxlen = stack[0]; for(int aim = maxlen; aim <= sumlen - aim; aim++) { if(sumlen % aim == 0 && DFS(stack, 0, aim, 0, vis, 0)) { //剪一:这么多棒子的总长度, 对所求的长度取余必须为0; printf("%d\n", aim); flag = 0; break; } } if(flag) printf("%d\n", sumlen); delete stack; delete vis; } return 0; }