一、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. Qt QImageReader 相似乎有bug

    Qt 版本号 5.4.1 (VS2010) 近期在做一个小程序,事实上非常easy,就是打开一个gif 动画.能够静态显示当中随意一帧图像.Qt 中有一个QImageReader 类.用这个类理论上说 ...

  2. CountDownTimer

    package com.daoge.widget; import java.text.DecimalFormat; import android.os.CountDownTimer; import a ...

  3. ASP.NET动态网站制作(0)

    前言:一直想系统地学习一下网站建设的相关内容,看过相关的书籍,也跟着视频学过,但总觉得效率不高,学过的东西印象不深刻,或许还是自己动手实践的少.无意中免费听了一堂讲ASP.NET网站建设的课,觉得性价 ...

  4. python 基础 1.4 python运算符

    一. 布尔值: 1>True 2>False       二.关系运算符 “=” (a=b):把b的值赋给a.等号赋值   “==”(a==b): 判断a与b是否相等.返回Trule或Fl ...

  5. springboot @ConfigurationProperties @EnableConfigurationProperties @Bean @ Component

    https://www.cnblogs.com/duanxz/p/4520571.html https://juejin.im/post/5cbeaa26e51d45789024d7e2 1. Bea ...

  6. 【BZOJ3771】Triple 生成函数+FFT

    [BZOJ3771]Triple Description 我们讲一个悲伤的故事. 从前有一个贫穷的樵夫在河边砍柴. 这时候河里出现了一个水神,夺过了他的斧头,说: “这把斧头,是不是你的?” 樵夫一看 ...

  7. 高性能流媒体服务器EasyDSS前端重构(三)- webpack + vue + AdminLTE 多页面引入 element-ui

    接上篇 接上篇<高性能流媒体服务器EasyDSS前端重构(二) webpack + vue + AdminLTE 多页面提取共用文件, 优化编译时间> 本文围绕着实现EasyDSS高性能流 ...

  8. 九度OJ 1155:鸡兔同笼 (基础题)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:2032 解决:1369 题目描述: 一个笼子里面关了鸡和兔子(鸡有2只脚,兔子有4只脚,没有例外).已经知道了笼子里面脚的总数a,问笼子里面 ...

  9. VM tools安装错误The path "" is not a valid path to the xx generic kernel headers.

    VMWARE TOOLS安装提示THE PATH IS NOT A VALID PATH TO THE GENERIC KERNEL HEADERSI solved this problem, I g ...

  10. 利用wxpython显示OpenCV图像

    核心代码 import wx, cv2 import numpy as np # Start with a numpy array style image I'll call "source ...