AcWing:167. 木棒(dfs + 剪枝)
乔治拿来一组等长的木棒,将它们随机地砍断,使得每一节木棍的长度都不超过50个长度单位。
然后他又想把这些木棍恢复到为裁截前的状态,但忘记了初始时有多少木棒以及木棒的初始长度。
请你设计一个程序,帮助乔治计算木棒的可能最小长度。
每一节木棍的长度都用大于零的整数表示。
注意: 数据中可能包含长度大于50的木棒,请在处理时忽略这些木棒。
输入格式
输入包含多组数据,每组数据包括两行。
第一行是一个不超过64的整数,表示砍断之后共有多少节木棍。
第二行是截断以后,所得到的各节木棍的长度。
在最后一组数据之后,是一个零。
输出格式
为每组数据,分别输出原始木棒的可能最小长度,每组数据占一行。
输入样例:
9
5 2 1 5 2 1 5 2 1
4
1 2 3 4
0
输出样例:
6
5
算法:dfs + 剪枝
题解:剪枝:1、优先搜索顺序(从大大小),优先尝试较长的木棒。
2、要求先后加入的木棒有单调性,因为你每根木棒都要用,之前加入和之后加入都是一个样。
3、当拼接一个新木棒时,我加入一个木棒,失败了,说明,之后用到这个木棒拼接一个新木棒的时候都会失败。
4、当我现在我要加入的木棒拼接上去,正好等于拼接的长度,但是拼接失败了,说明之后继续拼接下去也是失败。
#include <iostream>
#include <cstdio>
#include <algorithm> using namespace std; const int maxn = 1e5+; int arr[maxn];
int vis[maxn];
int k, cnt; bool cmp(int a, int b) {
return a > b;
} bool dfs(int stick, int cal, int last, int len) {
if(stick > cnt) { //当所有木棒已经拼好时,搜索成功
return true;
}
if(cal == len) { //木棒已经拼好,去拼下一根
return dfs(stick + , , , len);
}
int fail = ; //剪枝2,记录重复值
for(int i = last; i < k; i++) {
if(!vis[i] && cal + arr[i] <= len && fail != arr[i]) {
vis[i] = ;
if(dfs(stick, cal + arr[i], i + , len)) {
return true;
}
vis[i] = ;
fail = arr[i];
if(cal == || cal + arr[i] == len) { //剪枝3,剪枝4
return false;
}
}
}
return false; //当所有分支都尝试过,并且还没成功
} int main() {
int n;
while(~scanf("%d", &n) && n) {
int sum = , max_len = , x;
k = ;
for(int i = ; i <= n; i++) {
scanf("%d", &x);
if(x > ) {
continue;
}
sum += x;
max_len = max(max_len, x);
arr[k++] = x;
}
sort(arr, arr + k, cmp); //剪枝1
int i;
for(i = max_len; i <= sum; i++) {
if(sum % i != ) {
continue;
}
cnt = sum / i; //获取木棒的数量
for(int j = ; j < k; j++) {
vis[j] = ;
}
if(dfs(, , , i)) {
break;
}
}
printf("%d\n", i);
}
return ;
}
AcWing:167. 木棒(dfs + 剪枝)的更多相关文章
- acwing 167. 木棒
乔治拿来一组等长的木棒,将它们随机地砍断,使得每一节木棍的长度都不超过50个长度单位. 然后他又想把这些木棍恢复到为裁截前的状态,但忘记了初始时有多少木棒以及木棒的初始长度. 请你设计一个程序,帮助乔 ...
- AcWing:165. 小猫爬山(dfs + 剪枝)
翰翰和达达饲养了N只小猫,这天,小猫们要去爬山. 经历了千辛万苦,小猫们终于爬上了山顶,但是疲倦的它们再也不想徒步走下山了(呜咕>_<). 翰翰和达达只好花钱让它们坐索道下山. 索道上的缆 ...
- poj1011 && uva307 DFS + 剪枝
将木棒从大到小排列,保证每次的选择都是最长可选的木棒. 剪枝: 1 . 如果第 i 根木棒被选择却无法成功拼接,那么后面与其长度相同的也不能选择. 2 . 如果第 cnt + 1 根木棒无法成功拼接, ...
- poj 1011 :Sticks (dfs+剪枝)
题意:给出n根小棒的长度stick[i],已知这n根小棒原本由若干根长度相同的长木棒(原棒)分解而来.求出原棒的最小可能长度. 思路:dfs+剪枝.蛮经典的题目,重点在于dfs剪枝的设计.先说先具体的 ...
- Sticks(UVA - 307)【DFS+剪枝】
Sticks(UVA - 307) 题目链接 算法 DFS+剪枝 1.这道题题意就是说原本有一些等长的木棍,后来把它们切割,切割成一个个最长为50单位长度的小木棍,现在想让你把它们组合成一个个等长的大 ...
- *HDU1455 DFS剪枝
Sticks Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Subm ...
- POJ 3009 DFS+剪枝
POJ3009 DFS+剪枝 原题: Curling 2.0 Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 16280 Acce ...
- poj 1724:ROADS(DFS + 剪枝)
ROADS Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 10777 Accepted: 3961 Descriptio ...
- DFS(剪枝) POJ 1011 Sticks
题目传送门 /* 题意:若干小木棍,是由多条相同长度的长木棍分割而成,问最小的原来长木棍的长度: DFS剪枝:剪枝搜索的好题!TLE好几次,终于剪枝完全! 剪枝主要在4和5:4 相同长度的木棍不再搜索 ...
随机推荐
- Specialization For SCCM
JUST A LINK FOR ALL SCCM QUESTION http://eskonr.com/
- postman传数组参数,二维数组,多维数组
一维数组: 传递: 接收: 二维数组: 传递: 接收: 依此类推,
- 99乘法表(js)
//九九乘法表 let i,j,str; for(i=1;i<=9;i++) { str = ""; for(j=1;j<=i;j++) { str = str+i+' ...
- vuejs 深度监听
data: { obj: { a: 123 } }, 监听obj中a属性 watch: { 'obj.a': { handler(newName, oldName) { console.log('ob ...
- 安装.Net Framework 2.0出现 Error 25015
---------------------------Microsoft .NET Framework 2.0 安装程序---------------------------Error 25015.安 ...
- JAVA语言程序设计课后习题----第四单元解析(仅供参考)
1 本题水题,主要理解题目的意思即可,访问方法和修改方法可以通过快捷方式alt+insert选中你需要的成员变量即可 public class Person { public String name; ...
- tp5.1 nginx配置
解决方案 修改fastcgi的配置文件 目录:/www/server/nginx/conf/fastcgi.conf fastcgi_param PHP_ADMIN_VALUE "op ...
- thinkphp5 二维码生成
1.下载二维码插件Phpqrcode,地址 https://sourceforge.net/projects/phpqrcode/files/,把下载的文件夹放到\thinkphp\vendor下 2 ...
- 使用ViewFlipper实现图片轮播
public class MainActivity extends AppCompatActivity { private ViewFlipper flipper; //背景图片int[] id pr ...
- CentOS 安装 elasticsearch 注意点
注意点: 1. 从官网下载以 rpm 结尾的软件包 7.3.1版本 下载地址: https://artifacts.elastic.co/downloads/elasticsearch/elastic ...