将木棒从大到小排列,保证每次的选择都是最长可选的木棒。

剪枝:

1 . 如果第 i 根木棒被选择却无法成功拼接,那么后面与其长度相同的也不能选择。

2 . 如果第 cnt + 1 根木棒无法成功拼接,就应该立即重构第 cnt 根木棒。那么如何判断是否能构造木棍呢?每次可以选择的最长木棒必须要选择,因为就算这次不选择,后面木棒的拼接也要用到该木棒,如果不能利用该木棍直接返回构造上一根木棍。

3 . 如果现在加入长度为x的一节木棒刚好组成一节完整的木棒,但是后面的木棍不能成功拼接,就重新选取上一节木棍,改变最后需要的长度x。

AC代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 100;

int len[maxn], vis[maxn], n;
bool cmp(int a, int b){
	return a > b;
}

int Len, Cnt; //长度和数量 

bool dfs(int cnt, int cur, int lenth){
	if(cnt == Cnt) return true;
	for(int i = cur; i < n; ++i){
		if(vis[i] || lenth + len[i] > Len) continue;
		if(lenth + len[i] < Len){
			vis[i] = 1;
			if(dfs(cnt, i + 1, lenth + len[i])) return true;
			vis[i] = 0;
			if(lenth == 0) return false;
			while(len[i + 1] == len[i] && i < n) ++i; //len[i]没有被选择
		}
		else if(lenth + len[i] == Len){ //拼成1根
			vis[i] = 1;
			if(dfs(cnt + 1, 0, 0)) return true;
			vis[i] = 0;
			return false;
		}
	}
	return false;
}

int main(){
	while(scanf("%d", &n) == 1 && n){
		memset(vis, 0, sizeof(vis));
		int sum = 0;
		for(int i = 0; i < n; ++i){
			scanf("%d", &len[i]);
			sum += len[i];
		}
		sort(len, len + n, cmp); //根据长度降序排序 

		for(Len = len[0]; Len <= sum; ++Len){
			if(sum % Len) continue;
			Cnt = sum / Len;
			if(dfs(0, 0, 0)) {
				printf("%d\n", Len);
				break;
			}
		}
	}
	return 0;
}

如有不当之处欢迎指出!

poj1011 && uva307 DFS + 剪枝的更多相关文章

  1. poj1011(DFS+剪枝)

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

  2. poj1011 Sticks(dfs+剪枝)

    Sticks Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 110416   Accepted: 25331 Descrip ...

  3. POJ1011 (DFS+剪枝)

    Sticks Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 129606   Accepted: 30388 Descrip ...

  4. *HDU1455 DFS剪枝

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

  5. POJ 3009 DFS+剪枝

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

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

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

  7. DFS(剪枝) POJ 1011 Sticks

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

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

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

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

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

随机推荐

  1. linux ssh登录的小知识

    查看服务器的各个端口: # netstat -tulnp 或者 #netstat -tnip 筛选在后面添加 |grep *** 准许root登录 #vi /etc/ssh/sshd_config 找 ...

  2. sqlserver2008客户端设置主键自增

    是标识改为是

  3. 日历插件——laydate.js

    laydate是一款很好用的日历控件,兼容了包括IE6在内的所有主流浏览器,默认有三种皮肤,如需其它皮肤可去官网下载http://www.layui.com/laydate/  一.核心方法:layd ...

  4. Shell脚本中使用function(函数)示例

    这篇文章主要介绍了Shell脚本中使用function(函数)示例,本文着重讲解的是如何在shell脚本中使用自定义函数,并给出了两个例子,需要的朋友可以参考下   函数可以在shell script ...

  5. Notepad++ 运行java(转)

    Notepad++ 运行java java, 2013/05/04, 9 replies, 6,007 views 文章目录 Notepad++ for java 安装必须的程序 配置NppExec ...

  6. Jmeter3.1 使用技巧

    一.JMeter官网 下载地址 http://jmeter.apache.org/download_jmeter.cgi Jmeter wiki https://wiki.apache.org/jme ...

  7. Go笔记-流程控制

    [if] if 是用于测试某个条件的语句,如果该条件(逻辑型或布尔型)成立,则会执行大括号内的代码,第一个大括号必须和if 或者else同行,否则非法 // 方式1 if condition { // ...

  8. hadoop初学

    Hadoop: 官网(hadoop.apache.org)的定义: 一:Hadoop Common: 为Hadoop其它模块提供通用的支持 二:HDFS: 是Hadoop的分布式文件系统,其特点是高度 ...

  9. java 世界中Annotation

    java 世界中Annotation 在github上开始汇总一些自己学习,收集,总结,经验的一些信息,有利于跟踪,修改,提升.如果你感兴趣 可以关注一下,也可以提供自己的内容进来. https:// ...

  10. Linux 虚拟机忘记root密码

    Linux 虚拟机忘记root密码可以按照下面的步骤重新设置密码: 1.在grub界面,也就是有press any key的那个界面,按下任意键 2.键入e,出现三行文字,按上下键选择kernel那一 ...