Original question address
This question andSave Shaolin stickThe same question.
Use the given sticks to make up an equal-length stick and find the minimum length of the club.
The intuitive way of thinking in the bag is to enumerate all possible lengths, and then continuously test the combination of sticks. First, add the sticks to the combination, and then overwrite the combination if it is not suitable, and then test the next one, until all the sticks are overturned.
During enumeration, we only need to extend the length from the longest stick to the half of the total length of the stick. If it does not match, it means that all the sticks can only be combined into one stick.
I have read about poj before.Save Shaolin stickThis topic is described in detail. A dfs search question. Here, DFS has four pruning schemes:
- The length of the given stick may be repeated. If a combination scheme containing a stick is overturned, it is unnecessary to try the same length of the stick.
- In order to reduce repeated test schemes, such as testing the stick 1 2 3 solution is not suitable, it is unnecessary to test the small stick 1 3 2 later. Therefore, you must start the test in sequence. When the current stick is added to the combination scheme, if it does not constitute the target length, then the sticks to be tested will start from the next of the current sticks.
- To make up a stick of a certain length, the first one of which makes up the stick, how can we not make up the length with other sticks, so there is no need to overturn this first stick, simply overwrite the target length.
- If a stick X is added to the target length, the remaining sticks will no longer be available. So there is no need to overturn this stick X, to test other sticks, and directly overturn the target length.
At first I wrote all the four pruning methods. But it still times out and is speechless.
Finally, I found that there was a pruning in the main function outside DFS, which I didn't use,The length to be tested must be a factor of the total length; otherwise, it is unnecessary to test the length.. Because the stick is the same length, the length of each root is of course only the factor of the total length. That is, the pruning is not written, causing my timeout.
# Include <iostream> # include <cstring> # include <functional> # include <algorithm> using namespace STD; bool used [64]; int Len [64], n, l, last; bool DFS (int r, int m) {If (r = 0 & M = 0) return true; If (M = 0) M = L; int start = 0; If (M! = L) Start = last + 1; for (INT I = 0; I <n; I ++) {If (! Used [I] & Len [I] <= m) {if (I> 0) {If (used [I-1] = false & Len [I] = Len [I-1]) continue;} used [I] = true; last = I; if (DFS (R-1, M-len [I]) return true; else {used [I] = false; if (LEN [I] = M | M = L) return false ;}}return false;} int main () {While (CIN >> N) {If (! N) break; int Total = 0; For (INT I = 0; I <n; I ++) {CIN> Len [I]; total + = Len [I];} Sort (Len, Len + N, greater <int> (); For (L = Len [0]; L <= total/2; l ++) {If (Total % L) // no such timeout occurs .. Continue; memset (used, false, sizeof (used); If (DFS (n, l) {cout <L <Endl; break ;}} if (L> total/2) cout <total <Endl;} return 0 ;}