#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define DEBUG
#ifdef DEBUG
#define debug(...) printf( __VA_ARGS__)
#else
#define debug(...)
#endif
int n, len, count;
char found;
int stick[64];
int st[64]; /* st[k] = sum{a[k]...a[n-1]}, 某根木棒和所有比它短的木棒加起来的长度 */
char used[64];
static int
compare(const void *p1, const void *p2)
{
return *((int *)p2) - *((int *)p1);
}
/* 第k个小木棒开始搜索, sum:木棒还原好的长度, num: 已还原好的木棒数 */
void
dfs(int k, int sum, int num)
{
int i, pre;
if (num == count) {
found = 1;
return;
}
if (sum == len) {
dfs(0, 0, num+1);
}
else {
//从第k跟木棒开始搜索,如果有一根木棒满足:
//1 未被使用
//2 之前没有相同长度的木棒出现过
//3 它的长度加上已拼凑好的长度不会超过原始长度
//4 sum加上它自己和所有比它短的木棒的长度必须超过原始长度
//则把这根木棒拼凑过去
for (pre = -1, i = k; i < n; i++) {
if (!used[i] && stick[i] != pre && sum+stick[i] <= len && sum+st[i] >= len) {
pre = stick[i];
debug("选择%d加在第%d根木棒\n", stick[i], num+1);
used[i] = 1;
dfs(i+1, sum+stick[i], num);
if (found) return;
debug("否定%d\n", stick[i]);
used[i] = 0;
if (k == 0) break; /* 原始木棒的第1根木棒总是用长度最大的, 不用往后找 */
}
}
}
}
int
main()
{
int i, j, k, sum;
while (scanf("%d", &n), n != 0) {
sum = 0;
found = 0;
for (i = 0; i < n; i++) {
scanf("%d", stick+i);
sum += stick[i];
}
qsort(stick, n, sizeof(int), compare);
st[n-1] = stick[n-1];
for (i = n-2; i >= 0; i--) {
st[i] = st[i+1]+stick[i];
}
for (i = stick[0]; i <= sum; i++) {
if (sum % i == 0) {
debug("----------长度为%d的搜索过程------------\n", i);
len = i;
count = sum/i;
memset(used, 0, sizeof(used));
dfs(0, 0, 0);
debug("还原结果为: ");
for (k = 0; k < n; k++) {
debug("%d ", used[k]);
}
debug("\n\n");
if (found) {
break;
}
}
}
printf("%d\n", found? len : sum);
}
return 0;
}
分享到:
相关推荐
提供的代码文件"POJ3009-Curling 2.0【DFS+Vector+剪枝】.cpp"和"POJ3009-Curling 2.0【DFS+回溯+剪枝】.cpp"应该分别展示了如何在实际编程中应用这些技术,而"POJ3009-Curling 2.0.doc"则可能是解题报告,详细阐述...
标题“POJ3373-Changing Digits【DFS+强剪枝】”涉及的是一个编程竞赛中的问题,这个问题在北大POJ(北京大学在线评测系统)平台上被提出。"Changing Digits"是一个算法挑战,而解决方案是通过深度优先搜索(DFS)...
【标题】"POJ3733-Changing Digits【DFS+强剪枝】"是一个来自北京大学在线评测系统POJ的编程题目,该题目主要涉及深度优先搜索(DFS)算法和强剪枝策略。在算法竞赛和编程挑战中,这类问题通常要求参赛者通过编写...
1011(搜索+剪枝) POJ 1416 POJ 2676 POJ 1129:white_question_mark: 数据结构 串 POJ 1016 POJ 1035 POJ 3080 POJ 1936 排序(快排) POJ 1007 POJ 2388 POJ 1804 POJ 2299 高效查找 POJ 1002 POJ 3349 POJ 3274 ...
【标题】"POJ1020-Anniversary Cake【有技巧的DFS】"是一个源自北京大学在线编程平台POJ的编程题目,它涉及到深度优先搜索(DFS)算法的应用。这道题目要求参赛者通过编程解决一个有趣的问题,即在特定条件下如何...
包括深度优先遍历(DFS)和广度优先遍历(BFS),用于探索图的所有节点,是解决许多图问题的基础,如poj1860和poj3259所示。 #### 最短路径算法 Dijkstra算法、Bellman-Ford算法和Floyd算法分别适用于无负权边、有...
本文主要探讨了两种基础的搜索算法——深度优先搜索(DFS)和宽度优先搜索(BFS),以及剪枝策略,并通过POJ平台上的实例进行了分析。 1. **搜索算法基本概念** - **状态(state)**:表示问题在某个时间点的进展...
标题“POJ2676-Sudoku”指向的是北京大学在线编程平台POJ上的一道题目,编号为2676,题目内容与经典的数独游戏有关。解题报告和AC(Accepted)代码是该问题解决方案的组成部分,通常包括对问题的理解、算法设计、...
5. **搜索算法的优化**:poj1699、poj3411等训练搜索技巧和剪枝方法,poj3373、poj1691则介绍了记忆化搜索。 6. **更复杂的动态规划**:poj1191、poj1054等题目增加了动态规划的难度,引入了记录状态的DP和树型DP。 ...
2. DFS剪枝则更加多样化,包括: - 可行性剪枝:在遇到非法状态时立即终止搜索。 - 最优性剪枝:在最优化问题中,如果当前路径的代价超过了已找到的最优解,就无需继续该分支。 - 搜索顺序剪枝:通过改变搜索顺序...
这是一个典型的图搜索问题,常见的解决方法包括深度优先搜索(DFS)、广度优先搜索(BFS)以及A*搜索算法。 在八数码问题中,我们需要定义数据结构来表示当前的状态,通常是一个9个元素的一维数组,其中0代表空白...
标题中的“poj2488.rar_poj24_poj2488_方向模板法”指的是一个解决编程竞赛问题POJ2488的压缩文件,其中可能包含了解决该问题的代码示例。POJ是Programming Online Judge的缩写,是一个在线的编程竞赛平台,参与者...
3. 搜索技巧与剪枝:优化搜索效率,如POJ2531、POJ1416。 五、动态规划 1. 背包问题:如POJ1837、POJ1276,涉及0-1背包、完全背包等。 2. 表达式DP:常见于解决组合优化问题,如矩阵链乘法。 以上只是POJ题目分类...
6. **剪枝**:为了提高效率,可以设计剪枝条件,例如在搜索过程中,如果发现当前路径无法形成完整的遍历,就立即停止该路径的搜索,转向其他可能性。 7. **代码实现**:提供的源文件`POJ2488-A Knight's Journey....
1. **基础算法**:如排序算法(快速排序、归并排序、堆排序等)、搜索算法(深度优先搜索DFS、广度优先搜索BFS)、图论算法(最短路径Dijkstra、Floyd、Bellman-Ford)、动态规划(状态转移方程、剪枝技术等)、回溯...
- **定义**:包括深度优先遍历(DFS)和广度优先遍历(BFS)。 - **示例题目**: - poj1426 - poj3126 - poj2251 - poj2243 - poj3352 - poj1111 - poj3051 - poj1129 - poj2907 - **应用场景**:适用于...
6. **回溯与分支限界**:这类题目涉及到深度优先搜索和广度优先搜索,以及如何有效地剪枝来避免无效计算。 7. **图算法**:图论是计算机科学中的一大分支,题目可能涵盖DFS、BFS、最小生成树、最短路径等算法。 8....
### POJ 3009 Curling 2.0 解题报告 #### 问题描述与分析 本题属于经典的搜索类题目,要求我们利用给定的规则在一个类似于网格的地图上移动一个石头,从起点到达终点,并求出最少的步数。地图上除了起点和终点外,...
2. **最短路径**:虽然Dijkstra算法和Bellman-Ford算法更适合求解最短路径,但在特定情况下,DFS结合剪枝策略也能找出某些情况下的最短路径。 3. **拓扑排序**:在无环有向图(DAG)中,DFS可以进行拓扑排序,将所有...