POJ 1011 Sticks
2015-05-11 14:11
453 查看
传说中的入门级经典DFS搜索+剪枝,果然一看答案就会了
。。。
因为不存在顺序问题,当不符合条件时长棍更容易检测出来,所以从大到小排列。
朴素的DFS搜索:
剪枝思路:
① 原最小棍长一定是总和的因数
② 如果棍长不符合当前所有棍的和,就放弃搜索
③ 相等棍长的棍只用搜索一次
。。。
因为不存在顺序问题,当不符合条件时长棍更容易检测出来,所以从大到小排列。
朴素的DFS搜索:
int dfs( int temp_sum, int remain, int num){ int i; if( remain == 0){ if( num == 0) return 1; else remain = temp_sum; } for( i = 0; i < n; i++){ if( vis[i] == 0){ if( remain >= a[i]){ vis[i] = 1; if( dfs( temp_sum, remain-a[i], num-1)) return 1; vis[i] = 0; } } } return 0; }
剪枝思路:
① 原最小棍长一定是总和的因数
② 如果棍长不符合当前所有棍的和,就放弃搜索
③ 相等棍长的棍只用搜索一次
#include<stdio.h> #include<stdlib.h> #include<string.h> int cmp( const void* a, const void* b){ // 从大到小排列 return *(int*)b - *(int*)a; } int ans, n; int a[100], vis[100]; int dfs( int temp_sum, int remain, int num); int main(void){ int i, sum; while( scanf("%d", &n)!= EOF && n){ sum = 0; for( i = 0; i < n; i++){ scanf("%d", &a[i]); sum += a[i]; // 在这里求所有棍长的和 } qsort( a, n, sizeof(int), cmp); memset( vis, 0, sizeof(vis)); // 把访问数组设置为0 for( ans = 2; ans < sum; ans++){ if( sum % ans) continue; // 剪枝1:原最小棍长一定是总和的因数 else if( dfs( ans, ans, n)) break; } printf("%d\n", ans); } return 0; } int dfs( int temp_sum, int remain, int num){ // 参数设置:暂时的棍长用来试验,余下的长度,余下的棍数 int i; if( remain == 0){ // 满足了一次棍长 if( num == 0) return 1; // 若此时所有的木棍都被用过,则此时的棍长满足题意,返回成功 else remain = temp_sum; // 否则重置剩余棍长,继续试验 } for( i = 0; i < n; i++){ // 从第0根木棍开始试验 if( vis[i] == 0){ // 只试验未被访问的棍 if( remain >= a[i]){ // 若此时棍长小于剩余棍长 vis[i] = 1; // 假设使用 if( dfs( temp_sum, remain-a[i], num-1)) return 1; // 继续向下搜索,若满足条件停止搜索 vis[i] = 0; // 所有搜索都不满足条件,则此木棍不在当前组合中 if( a[i] == remain || remain == temp_sum) break; // 剪枝2:若没有符合条件的木棍,说明当前棍长不符合条件,认为失败,停止搜索 while( a[i] == a[i+1]) i++; // 剪枝3:如果随后的木棍和此木棍相同长度,则跳过不搜索 } } } return 0; // 返回失败 }
相关文章推荐
- POJ 1011 Sticks
- POJ-1011-Sticks
- POJ 1011:Sticks 经典搜索
- poj1011——Sticks
- POJ 1011 Sticks
- 【北大夏令营笔记-深度优先搜索】POJ1011-Sticks
- POJ 1011 Sticks
- 【DFS剪枝】poj 1011 Sticks
- POJ 1011 Sticks
- POJ1011 Sticks
- poj 1011 Sticks
- 搜索+剪枝——POJ 1011 Sticks
- POJ 1011 Sticks 解题报告
- POJ 1011 STICKS 搜索 剪枝
- POJ 1011 - Sticks
- poj 1011 :Sticks (dfs+剪枝)
- poj 1011 sticks (dfs + 剪枝)
- POJ 1011 Sticks (dfs + 厉害的剪枝)
- POJ-1011-Sticks-DFS(深搜)+四次剪枝
- uva 215 hdu 1455 uvalive5522 poj 1011 sticks