acwing 167. 木棒

喬治拿來一組等長的木棒,將它們隨機地砍斷,使得每一節木棍的長度都不超過50個長度單位。ios

而後他又想把這些木棍恢復到爲裁截前的狀態,但忘記了初始時有多少木棒以及木棒的初始長度。數組

請你設計一個程序,幫助喬治計算木棒的可能最小長度。ide

每一節木棍的長度都用大於零的整數表示。函數

注意: 數據中可能包含長度大於50的木棒,請在處理時忽略這些木棒。優化

輸入格式

輸入包含多組數據,每組數據包括兩行。spa

第一行是一個不超過64的整數,表示砍斷以後共有多少節木棍。設計

第二行是截斷之後,所獲得的各節木棍的長度。code

在最後一組數據以後,是一個零。blog

輸出格式

爲每組數據,分別輸出原始木棒的可能最小長度,每組數據佔一行。排序

 

 

 

個人TLE代碼  改爲c的數組操做才經過

 1 // 11111111.cpp : 此文件包含 "main" 函數。程序執行將在此處開始並結束。
 2 //
 3 
 4 #include "pch.h"
 5 #include <iostream>
 6 
 7 #include <iostream>
 8 #include <algorithm>
 9 #include <memory.h>
10 
11 using namespace std;
12 
13 int n, m;
14 
15 const int N = 65;
16 int arr[N];
17 int realCount;
18 int maxLen = 0;
19 int sum = 0;
20 int len;
21 int tryCnt;
22 int vis[N];
23 
24 int cmp(int a, int b)//從大到小排序
25 {
26     return a > b;
27 }
28 
29 bool dfs(int segCount, int segLen, int lastSelect)
30 {
31     bool bret = false;
32     if (segCount == tryCnt) return true;
33     if (segLen == len) return dfs(segCount + 1, 0, 0);
34     int fail = 0;
35     for (int i = lastSelect; i < realCount; i++) {
36 
37         if (!vis[i] && arr[i] != fail && segLen + arr[i] <= len)//沒有被訪問,不是上一次失敗的值,長度知足在len之內
38         {
39             vis[i] = 1;
40             if (dfs(segCount, segLen + arr[i], i + 1))//開始下一次dfs
41                 return true;
42             fail = arr[i];//失敗了,固然要記錄了
43             vis[i] = 0;//這個數沒有選擇
44             if (segLen == 0 || segLen + arr[i] == len)//若是cab爲0,或者相加正好是len,可是失敗了,那麼必定是失敗了.
45                 return false;
46         }
47     }
48 
49     return false;
50 }
51 
52 
53 int main()
54 {
55     ios::sync_with_stdio(false);
56 
57     while (cin >> n && (n != 0)) {
58         int sum = 0;
59         for (int i = 0; i < n; i++) {
60             int tmp;
61             cin >> tmp;
62             if (tmp > 50)
63                 continue;
64             arr[realCount] = tmp;
65             maxLen = max(maxLen, arr[realCount]);
66             sum += arr[realCount++];
67         }
68         sort(arr, arr + realCount,cmp);
69 
70 
71         for (len = maxLen; len <= sum; len++)//優化
72         {
73             if (sum%len)//若是除不盡,確定不知足題意
74                 continue;
75             tryCnt = sum / len;//計算出cnt多少段
76             //cout << "sum = " << sum << ".  len = " << len << endl;
77             memset(vis, 0, sizeof(vis));//初始化
78             if (dfs(0, 0, 0))//搜索成功,最小值就是它
79                 break;
80         }
81         cout << len << endl;
82     }
83 
84 
85     return 0;
86 }
View Code
相關文章
相關標籤/搜索