Sticks(剪枝+BFS)

简介: Problem Description George took sticks of the same length and cut them randomly until all parts became at most 50 units long.

Problem Description

George took sticks of the same length and cut them randomly until all parts became at most 50 units long. Now he wants to return sticks to the original state, but he forgot how many sticks he had originally and how long they were originally. Please help him and design a program which computes the smallest possible original length of those sticks. All lengths expressed in units are integers greater than zero.

Input

The input contains blocks of 2 lines. The first line contains the number of sticks parts after cutting, there are at most 64 sticks. The second line contains the lengths of those parts separated by the space. The last line of the file contains zero.

Output

The output file contains the smallest possible length of original sticks, one per line.

SampleInput

9
5 2 1 5 2 1 5 2 1
4
1 2 3 4
0

SampleOutput

6
5

题意就是给你一堆不同长度的木棍,要你用他们拼成长度相等的木棍,输出最短且满足要求的木棍长度。
就直接从0开始搜嘛,判断长度相同就输出,好了就这样,提交,TLE。
=7=那么看来不能直接搜索,如何优化呢,当然就是判断一些条件剪枝,首先是搜索范围,根据题意有原始长度肯定比现在最长的要长,而且能被现在总长除尽,原始长度最长肯定就是总长度(只有一根木棍),其次就是对于同一个长度的木棍,只尝试一次,一次不成功便不需要尝试第二次,然后就依次dfs就行了。
代码:
 1 #include <iostream>
 2 #include <string>
 3 #include <cstdio>
 4 #include <cstdlib>
 5 #include <sstream>
 6 #include <iomanip>
 7 #include <map>
 8 #include <stack>
 9 #include <deque>
10 #include <queue>
11 #include <vector>
12 #include <set>
13 #include <list>
14 #include <cstring>
15 #include <cctype>
16 #include <algorithm>
17 #include <iterator>
18 #include <cmath>
19 #include <bitset>
20 #include <ctime>
21 #include <fstream>
22 #include <limits.h>
23 #include <numeric>
24 
25 using namespace std;
26 
27 #define F first
28 #define S second
29 #define mian main
30 #define ture true
31 
32 #define MAXN 1000000+5
33 #define MOD 1000000007
34 #define PI (acos(-1.0))
35 #define EPS 1e-6
36 #define MMT(s) memset(s, 0, sizeof s)
37 typedef unsigned long long ull;
38 typedef long long ll;
39 typedef double db;
40 typedef long double ldb;
41 typedef stringstream sstm;
42 const int INF = 0x3f3f3f3f;
43 
44 int s[500050];
45 bool vis[500050];
46 int sum,n;
47 
48 bool dfs(int pos, int res, int len){
49     if(pos == 0 && res == 0)
50         return true;
51     if(!res)
52         res = len;
53     for(int i = n - 1; i >= 0; i--){
54         if(vis[i] || s[i] > res)
55             continue;
56         vis[i] = true;
57         if(dfs(pos - 1, res - s[i], len))
58             return true;
59         vis[i] = false;
60         if(res == s[i] || res == len)    //判断是否尝试过
61             return false;
62     }
63     return false;
64 }
65 
66 int main(){
67     ios_base::sync_with_stdio(false);
68     cout.tie(0);
69     cin.tie(0);
70     while(cin >> n && n){
71         sum = 0;
72         for(int i = 0; i < n; i++){
73             cin >> s[i];
74             sum += s[i];
75         }
76         sort(s, s+n);
77         int i;
78         for(i = s[n - 1]; i <= sum/2;i++){    //从最大长度开始dfs
79             if(sum % i)  //小于总长度则dfs尝试
80                 continue;
81             MMT(vis);  //每次dfs前记得清空标记
82             if(dfs(n,i,i)){
83                 cout << i << endl;
84                 break;
85             }
86         }
87         if(i > sum/2)    //大于长度一半,则不可能被分成多个木棍,肯定只能由一根木棍构成
88             cout << sum << endl;
89     }
90     return 0;
91 }
 
  

 

目录
相关文章
|
12月前
|
算法 C++
用prim和kruskal算法求最小生成树问题
用prim和kruskal算法求最小生成树问题
80 0
|
存储 容器
华为机试HJ41:称砝码(深度优先遍历dfs-Depth First Search)
华为机试HJ41:称砝码(深度优先遍历dfs-Depth First Search)
135 0
|
存储 算法
最短路径算法( Dijkstra + Bellman-Ford + SPFA + Floyd)
最短路径算法( Dijkstra + Bellman-Ford + SPFA + Floyd)
170 0
|
人工智能
POJ 2299 Ultra-QuickSort(树状数组+离散化+求逆序数)
POJ 2299 Ultra-QuickSort(树状数组+离散化+求逆序数)
|
存储 算法
最短路径——Bellman-Ford算法以及SPFA算法
最短路径——Bellman-Ford算法以及SPFA算法
最短路径——Bellman-Ford算法以及SPFA算法
|
机器学习/深度学习 算法 程序员
【算法合集】深搜广搜Prim与Kruskal
广度优先搜索(BFS)又叫广搜,它像一个有远见的人,它是一层一层来实现搜索的,也挺像下楼梯的。 思路: 1.先初始化队列 q; 2.从起点开始访问,并且改变他的状态为已经访问; 3.如果他的队列非空,取出首个元素,将它弹出! 4.如果u == 目标状态,然后对所以与 u 邻近的点进入队列; 5.标记它已经被访问!...............
169 1
【算法合集】深搜广搜Prim与Kruskal
|
算法 调度
最小生成树(Prim、Kruskal)算法,秒懂!
在数据结构与算法的图论中,(生成)最小生成树算法是一种常用并且和生活贴切比较近的一种算法。但是可能很多人对概念不是很清楚,什么是最小生成树?
181 0
最小生成树(Prim、Kruskal)算法,秒懂!
UPC Graph (最小生成树 || 并查集+二分)
UPC Graph (最小生成树 || 并查集+二分)
92 0
|
算法
图论最短路及生成树(Prim,Djikstra,Spfa,Bellan-ford,kruskal,topsort)
图论最短路及生成树(Prim,Djikstra,Spfa,Bellan-ford,kruskal,topsort)
138 1