一、Description

乔治拿来一组等长的木棒,将它们随机地砍断,使得每一节木棍的长度都不超过50个长度单位。然后他又想把这些木棍恢复到为裁截前的状态,但忘记了初始时有多少木棒以及木棒的初始长度。请你设计一个程序,帮助乔治计算木棒的可能最小长度。每一节木棍的长度都用大于零的整数表示。

Input

输入包含多组数据,每组数据包括两行。第一行是一个不超过64的整数,表示砍断之后共有多少节木棍。第二行是截断以后,所得到的各节木棍的长度。在最后一组数据之后,是一个零。

Output

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

二、问题分析

网上找到的题解,很棒:http://www.cppblog.com/y346491470/articles/155318.html

【题解】:下面说下几个重要的剪枝:

1.把所有木棍的长度从大到小排列,组合木棒时优先使用长的木棍,这样可以加快组合速度,并且对后面的剪枝有帮助。

2.木棒的长度一定是大于等于最长木棍的长度并且小于等于所有木棍长度的和,这个很容易证明。

3.木棒的长度一定是所有木棍长度的和的约数,这个也很容易证明。

4.在某一个木棒的组合过程中,对于当前的木棍stick[i],如果stick[i-1]没有被组合并且stick[i] == stick[i-1],那么不用考虑stick[i],显然stick[i]最终也不会被组合。

5.如果此次是在尝试第i个木棒的第一段,假设stick[j]为当前可以被使用的最长的木棍,如果此次组合失败,直接退出搜索,即退回到对第i-1个木棒的搜索。试想:失败说明现在使用stick[j]是不可行的,那么以后无论什么时候使用stick[j]都是不可行的,因为以后再处理stick[j]时可使用的木棍一定是当前可使用的木棍的子集,在更多木棍选择的情况下都不能组合成功,那么,在更少木棍选择的情况下一定不能组合成功。

三、问题解决

第一次听到“剪枝”:没有 正式的解释,大概意思是:就是在做搜索的时候,当你确定某些决策一定不可能得到答案的时候,就不必再搜索这个决策了,这样可以减少搜索量,加快程序速度,对于具体的问题是需要一些技巧的,最常见的就是可行性剪枝(当前状态一定不会出解)和最优性剪枝(当前状态即使出解了也一定不会最优)了。

这个问题涉及到排序和搜索算法,我用了QS和DFS。

import java.util.Scanner;

public class N1011_Sticks{

	static int[] sticks;
static boolean[] visited;
static int n;
static int st; public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
while ((n = scan.nextInt()) != 0) {
int sum = 0;
sticks = new int[n];
visited = new boolean[n];
for (int i = 0; i < n; i++) {
sticks[i] = scan.nextInt();
sum += sticks[i];
}
quicksort(0, n - 1);
boolean flag = false;
for (int ini = sticks[0]; ini < sum; ini++) {
if (sum % ini == 0 && dfs(0, 0, ini, 0)) {
System.out.println(ini);
flag = true;
break;
}
}
if (!flag) {
System.out.println(sum);
}
}
} static boolean dfs(int len, int s, int ini, int am) {
if (am == n) {
return true;
} int sp = -1; for (int i = s; i < n; i++) {
if (visited[i] || sticks[i] == sp) {
continue;
}
visited[i] = true;
if (len + sticks[i] < ini) {
if (dfs(len + sticks[i], i, ini, am + 1)) {
return true;
} else {
sp = sticks[i];
}
} else if (len + sticks[i] == ini) {
if (dfs(0, 0, ini, am + 1)) {
return true;
} else {
sp = sticks[i];
}
} visited[i] = false; if (len == 0) {
return false;
}
}
return false;
} static void quicksort(int p, int r) {
if (p < r) {
int a = part(p, r);
quicksort(p, a - 1);
quicksort(a + 1, r);
}
} static int part(int p, int r) {
int x = sticks[r];
int i = p - 1;
int j = p;
for (; j < r; j++) {
if (sticks[j] > x) {
i++;
int k = sticks[i];
sticks[i] = sticks[j];
sticks[j] = k;
}
}
int k = sticks[i + 1];
sticks[i + 1] = sticks[j];
sticks[j] = k;
return i + 1;
}
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

Poj_1011_Sticks(剪枝)的更多相关文章

  1. α-β剪枝算法的java语言实现(非常实用)

    利用α-β剪枝算法,对下图所示的博弈树进行搜索,搜索得到根节点选择的走步,以及没有必要进行评估的节点,并求出给出在何处发生了剪枝,以及剪枝的类型(属于α剪枝还是β剪枝). 注:□表示MIN节点:○表示 ...

  2. Sicily 1153: 马的周游问题(DFS+剪枝)

    这道题没有找到一条回路,所以不能跟1152一样用数组储存后输出.我采用的方法是DFS加剪枝,直接DFS搜索会超时,优化的方法是在搜索是优先走出度小的路径,比如move1和move2都可以走,但是如走了 ...

  3. HDU5887 Herbs Gathering(2016青岛网络赛 搜索 剪枝)

    背包问题,由于数据大不容易dp,改为剪枝,先按性价比排序,若剩下的背包空间都以最高性价比选时不会比已找到的最优解更好时则剪枝,即 if(val + (LD)pk[d].val / (LD)pk[d]. ...

  4. HDU5937 Equation(DFS + 剪枝)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5937 Description Little Ruins is a studious boy, ...

  5. alpha-beta剪枝搜索

    •一种基于剪枝( α-βcut-off)的深度优先搜索(depth-first search). •将走棋方定为MAX方,因为它选择着法时总是对其子节点的评估值取极大值,即选择对自己最为有利的着法: ...

  6. POJ1190生日蛋糕[DFS 剪枝]

    生日蛋糕 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 18236   Accepted: 6497 Description ...

  7. *HDU1455 DFS剪枝

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

  8. HDU1010 DFS+剪枝

    Tempter of the Bone Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Othe ...

  9. HDU 5113 dfs剪枝

    题意:告诉格子规格,颜色个数,以及每个颜色能涂得格子数目,问是否能够实现相邻两个格子的颜色数目不相同. 分析:因为数据很小,格子最多是5 * 5大小的,因此可以dfs.TLE了一次之后开始剪枝,31m ...

随机推荐

  1. Struts2实现input数据回显

    /** 修改页面 */    public String editUI() {        //准备回显得数据        Role role = roleService.getById(id); ...

  2. Centos 7.0防火墙问题

    从Centos7开始,自带的防火墙从iptables更改成了firewall.一般在企业环境,出于人力和稳定性考虑,还是用成熟的技术比较稳妥. 以下是关闭firewall的方法 systemctl s ...

  3. 向oracle中插入date时,持久层sql怎么写???

    public class EmpDao { public void addEmp(Emp emp) throws SQLException { QueryRunner runner = new Que ...

  4. 【PyCharm编辑器】之引用selenium包提示错误:Unresolved reference 'selenium' less... (Ctrl+F1)

    一.现象还原: 当新建.py文件时,需要引用selenium中的方法时,报错,提示红波浪线: Unresolved reference 'selenium' less... (Ctrl+F1) Thi ...

  5. 17 redis -key设计原则

    书签系统 create table book ( bookid int, title char(20) )engine myisam charset utf8; insert into book va ...

  6. 多媒体开发之---h264中 的RTP PAYLOAD 格式

    H.264 视频 RTP 负载格式 1. 网络抽象层单元类型 (NALU) NALU 头由一个字节组成, 它的语法如下: +---------------+      |0|1|2|3|4|5|6|7 ...

  7. 统计分析表的存储过程遇ORA-00600错误分析与处理

    1.            统计分析表的存储过程部分内容 CREATE OR REPLACE procedure SEA.sp_analyze_XXX_a is v_sql_1     varchar ...

  8. 【Android】百度地图自定义弹出窗口

    我们使用百度地图的时候,点击地图上的Marker,会弹出一个该地点详细信息的窗口,如下左图所示,有时候,我们希望自己定义这个弹出窗口的内容,或者,干脆用自己的数据来构造这样的弹出窗口,但是,在百度地图 ...

  9. UIScrollView奇葩不滑动

    首先要说声尼玛,真奇葩,从来都没有遇到过这个问题,首先描述一下背景: 我是用XIB拖拽了一个UIScrollView在View上,然后设置了frame,在ViewDidLoad里面,设置了scroll ...

  10. python 基础 1.5 python数据类型(二)--列表常用方法示例

    #/usr/bin/python #coding=utf-8 #@Time   :2017/10/12 23:30 #@Auther :liuzhenchuan #@File   :列表.py lis ...