Poj_1011_Sticks(剪枝)
一、Description
Input
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(剪枝)的更多相关文章
- α-β剪枝算法的java语言实现(非常实用)
利用α-β剪枝算法,对下图所示的博弈树进行搜索,搜索得到根节点选择的走步,以及没有必要进行评估的节点,并求出给出在何处发生了剪枝,以及剪枝的类型(属于α剪枝还是β剪枝). 注:□表示MIN节点:○表示 ...
- Sicily 1153: 马的周游问题(DFS+剪枝)
这道题没有找到一条回路,所以不能跟1152一样用数组储存后输出.我采用的方法是DFS加剪枝,直接DFS搜索会超时,优化的方法是在搜索是优先走出度小的路径,比如move1和move2都可以走,但是如走了 ...
- HDU5887 Herbs Gathering(2016青岛网络赛 搜索 剪枝)
背包问题,由于数据大不容易dp,改为剪枝,先按性价比排序,若剩下的背包空间都以最高性价比选时不会比已找到的最优解更好时则剪枝,即 if(val + (LD)pk[d].val / (LD)pk[d]. ...
- HDU5937 Equation(DFS + 剪枝)
题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5937 Description Little Ruins is a studious boy, ...
- alpha-beta剪枝搜索
•一种基于剪枝( α-βcut-off)的深度优先搜索(depth-first search). •将走棋方定为MAX方,因为它选择着法时总是对其子节点的评估值取极大值,即选择对自己最为有利的着法: ...
- POJ1190生日蛋糕[DFS 剪枝]
生日蛋糕 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 18236 Accepted: 6497 Description ...
- *HDU1455 DFS剪枝
Sticks Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Subm ...
- HDU1010 DFS+剪枝
Tempter of the Bone Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Othe ...
- HDU 5113 dfs剪枝
题意:告诉格子规格,颜色个数,以及每个颜色能涂得格子数目,问是否能够实现相邻两个格子的颜色数目不相同. 分析:因为数据很小,格子最多是5 * 5大小的,因此可以dfs.TLE了一次之后开始剪枝,31m ...
随机推荐
- 必会必知git
git必会必知 1 前言 git前身是BitKeeper,但是他不是开源软件,不符合当时开源趋势,于是就会有了开源的git,git开发只用了十天时间.目前git是公司开发必不可少的一个工具,用于多 ...
- Jquery EasyUI弹出窗体
$("#btnCreate").click(function () { $("#modalwindow").html("<iframe widt ...
- 【PHP开发】远程文件(图片)下载
这一篇文章介绍的方法不算原创了,只是引用的别人的文章,加上自己的注释,因为接触php时间不长,所以尝试的东西比较多,自己加的注释也比较简单,php高手请略过. 我要用到远程下载图片,是在做微信公众平台 ...
- 九度OJ 1081:递推数列 (递归,二分法)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:6194 解决:864 题目描述: 给定a0,a1,以及an=p*a(n-1) + q*a(n-2)中的p,q.这里n >= 2. 求第 ...
- CALL FUNCTION 'BAPI_GOODSMVT_CREATE'-(物料凭证创建)
*&---------------------------------------------------------------------* *& Report YTST_RAI ...
- 改善程序与设计的55个具体做法 day1
博客好久没更新了,就从这本读书笔记开始吧. 条款01: 视C++为一个语言联邦 C++可视为有四个次语言组成的: 1.C语言 2.Object-Oriented C++ (面向对象C++) 3.Tem ...
- 4.1 《锋利的jQuery》jQuery中的事件
$(document).ready()方法和window.onload方法的区别 事件绑定 合成事件 事件冒泡 事件对象的属性 tip1:停止事件冒泡和阻止默认行为都可以用return false替代 ...
- CSS3 3D下拉折叠菜单
在线演示 本地下载
- csrf防范笔记
1.验证Http的refer字段 http有一个refer字段,用以记录该http请求的来源地址 好处: 简单便捷,后台开发人员只需要设置一个拦截器 缺点: Referer 的值是由浏览器提供的,虽然 ...
- 素数筛总结篇___Eratosthenes筛法和欧拉筛法(*【模板】使用 )
求素数 题目描述 求小于n的所有素数的数量. 输入 多组输入,输入整数n(n<1000000),以0结束. 输出 输出n以内所有素数的个数. 示例输入 10 0 示例输出 4 提示 以这道题目为 ...