acwing 167. 木棒

乔治拿来一组等长的木棒,将它们随机地砍断,使得每一节木棍的长度都不超过50个长度单位。

然后他又想把这些木棍恢复到为裁截前的状态,但忘记了初始时有多少木棒以及木棒的初始长度。

请你设计一个程序,帮助乔治计算木棒的可能最小长度。

每一节木棍的长度都用大于零的整数表示。

注意: 数据中可能包含长度大于50的木棒,请在处理时忽略这些木棒。

输入格式

输入包含多组数据,每组数据包括两行。

第一行是一个不超过64的整数,表示砍断之后共有多少节木棍。

第二行是截断以后,所得到的各节木棍的长度。

在最后一组数据之后,是一个零。

输出格式

为每组数据,分别输出原始木棒的可能最小长度,每组数据占一行。

 

我的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
作 者: itdef
欢迎转帖 请保持文本完整并注明出处
技术博客 http://www.cnblogs.com/itdef/
B站算法视频题解
https://space.bilibili.com/18508846
qq 151435887
gitee https://gitee.com/def/
欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
如果觉得不错,欢迎点赞,你的鼓励就是我的动力
阿里打赏 微信打赏
原文地址:https://www.cnblogs.com/itdef/p/10945328.html