Sticks

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 13807    Accepted Submission(s): 4270

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. 
 
Sample Input
9
5 2 1 5 2 1 5 2 1
4
1 2 3 4
0
 
Sample Output
6
5

我做的第二道dfs题。。。

题意:给出n个小木棒的长度,他们是又数根长度相同的木棒剪短得来的,问没剪短之前的木棒长度最短是多少

题解:要把这些小木棒拼接成数根长度相同的长木棒。要用到搜索算法。但因为搜索算法时间复杂度较高,需要剪枝才行。可以先给小木棒从大到小排个序,最后拼成的长木棒长度肯定在小木棒长度最大值和所有小木棒加起来的长度之间(因为是拼起来的,不可能比原来小木棒还短)。然后判断小木棒长度总和与假设的长木棒原长是不是整除关系。是的话就按照这个假设长度搜索,看不能全部拼成。

 #include<bits/stdc++.h>
using namespace std;
const int maxn = ;
const int INF = 0x3f3f3f3f;
int n, sumv, target, aim;//target表示目标的棍子个数,aim表示目标的棍子长度,sumv为所有木棍总长度
int stick[maxn], vis[maxn];//vis数组标记 ,stick存储输入的木棒长度
bool cmp(int a, int b) {
return a > b;
}
bool dfs(int cnt, int len, int pos) {
if(cnt == target) return true;//根数对上就返回 退出dfs
if(len == aim) return dfs(cnt+, , ); //当拼完一根后,继续拼下一根
for(int i = pos; i < n; i++) {//从大到小排序后,按顺序搜索
if(!vis[i] && len+stick[i] <= aim) {
vis[i] = ;
if(dfs(cnt, len+stick[i], i+)) return true;
vis[i] = ; //只有失败才会运行到下面,否则是直接返回的
if(len == ) return false; //如果第一根时失败 剪枝
while(i+ < n && stick[i+] == stick[i]) i++; //如果下一根长度跟当前的失败的长度一样,剪枝
}
}
return false;
}
int main() {
while(~scanf("%d", &n), n) {
sumv = ;
for(int i = ; i < n; i++) {
scanf("%d",&stick[i]);
sumv += stick[i];
}
sort(stick, stick+n, cmp);
int ans = ;
for(int i = stick[]; i <= sumv; i++) {//拼好后的木棒长度只会在stick[0]和总长度之间
if(sumv % i == ) {
memset(vis, , sizeof(vis));
aim = i;
target = sumv / aim;
if(dfs(, , )) {
ans = aim;
break;
}
}
}
printf("%d\n",ans);
}
return ;
}

hdu1455Sticks(经典dfs+剪枝)的更多相关文章

  1. poj 1011 :Sticks (dfs+剪枝)

    题意:给出n根小棒的长度stick[i],已知这n根小棒原本由若干根长度相同的长木棒(原棒)分解而来.求出原棒的最小可能长度. 思路:dfs+剪枝.蛮经典的题目,重点在于dfs剪枝的设计.先说先具体的 ...

  2. poj1011(DFS+剪枝)

    题目链接:https://vjudge.net/problem/POJ-1011 题意:给定n(<=64)条木棍的长度(<=50),将这些木棍刚好拼成长度一样的若干条木棍,求拼出的可能的最 ...

  3. *HDU1455 DFS剪枝

    Sticks Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Subm ...

  4. POJ 3009 DFS+剪枝

    POJ3009 DFS+剪枝 原题: Curling 2.0 Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 16280 Acce ...

  5. poj 1724:ROADS(DFS + 剪枝)

    ROADS Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10777   Accepted: 3961 Descriptio ...

  6. DFS(剪枝) POJ 1011 Sticks

    题目传送门 /* 题意:若干小木棍,是由多条相同长度的长木棍分割而成,问最小的原来长木棍的长度: DFS剪枝:剪枝搜索的好题!TLE好几次,终于剪枝完全! 剪枝主要在4和5:4 相同长度的木棍不再搜索 ...

  7. DFS+剪枝 HDOJ 5323 Solve this interesting problem

    题目传送门 /* 题意:告诉一个区间[L,R],问根节点的n是多少 DFS+剪枝:父亲节点有四种情况:[l, r + len],[l, r + len - 1],[l - len, r],[l - l ...

  8. HDU 5952 Counting Cliques 【DFS+剪枝】 (2016ACM/ICPC亚洲区沈阳站)

    Counting Cliques Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

  9. HDU 5937 Equation 【DFS+剪枝】 (2016年中国大学生程序设计竞赛(杭州))

    Equation Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

随机推荐

  1. 阿里云linux服务器登录失败,Connection closed

    ssh_exchange_identification: read: Connection reset by peer报错如下: [root@izbp17x1~]# ssh admin@139.196 ...

  2. centos7 yum安装mysql后启动不起来问题

    [root@localhost ~]# systemctl start mysqld       启动失败 Job for mysqld.service failed because the cont ...

  3. JAVA交通规则

    第一个JAVA程序的编写和运行 1.使用记事本编辑: public class Welcome { public static void main(String[] args) { System.ou ...

  4. 装饰器概念&实际使用干货

    定义: 本质是函数(装饰其他函数),是为其他函数添加附加功能 原则: 不能修改被装饰函数的源代码 不能修改被装饰函数的调用方式   实现装饰器知识储备: 函数及“变量” 高阶函数 把一个函数名当做实参 ...

  5. 微信小程序中的app文件介绍

    [app] 一.app.json 1.对当前小程序的全局配置 2.页面路径.界面表现.网络超时时间.底部 tab 等 { "pages":[ "pages/index/i ...

  6. E. K Balanced Teams

    类比背包问题,为每个学生附加一个权重$pos[i]$,意思是选择该学生后,之后可以选择$p[i]~p[i]+5$的学生. 转换公式: $$d[i][j]=max(d[i+1][q],d[i+pos][ ...

  7. 【C++ Primer】读书笔记_第一章

    Main(): 1. C++程序必须包含main()函数,操作系统通过调用main来运行C++程序. 2. main()的形参可以为空. 3. main函数的返回类型必须为int,返回给操作系统.in ...

  8. 如何优雅的使用C语言绘制一只小猪佩奇

    今天我们来用C语言画一只小猪佩奇---社会.社会....在画小猪佩奇之前,我们先使用带符号的距离长 (signed distance field,SDF) 来画一个圆形. 使用这个方法表示形状,但是这 ...

  9. Elasticsearch 数据查询

    数据准备: PUT /shop { "settings": { "number_of_shards": 3, "number_of_replicas& ...

  10. windows10下“sqlplus / as sysdba”执行提示无权限解决办法

    ORA_DBA:是ORACLE 的特有用户,是超级管理员权限,建成DBA 它具有管理数据库的最高权限. 注明:需要以管理员身份运行cmd,不然第4步会失败(点开始,输入cmd,右键以管理员身份运行) ...