POJ 1011 (13.07.23)

来源:互联网 发布:微博营销 seo 编辑:程序博客网 时间:2024/06/05 16:30

 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

95 2 1 5 2 1 5 2 141 2 3 40

Sample Output

65题意:找出一个最短长度, 使得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;elsesame = stack[i];}else if(curlen + stack[i] == aimlen) {if(DFS(stack, 0, aimlen, 0, vis, num+1))return 1;elsesame = 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;}