UVa307 - Sticks(DFS+剪枝)

来源:互联网 发布:linux 线程挂起 编辑:程序博客网 时间:2024/05/10 11:00

题意:给出若干个一样长的sticks,剪断后有n个部分,问原来sticks的最小长度。

思路:首先要确定sticks的长度范围,范围应该在[max(n1,n2..., n), sum(n1,n2...,n)}之间。然后用深度优先算法,在深搜时注意剪枝

(1)如果当前木棒搜索没有成功,那么后面的木棒长度与当前木棒长度一样,就应该跳过。

(2)如果当前木棒是第一个是没有成功,后面的也不会成功

#include <cstdio>#include <algorithm>#include <limits>#include <cstring>#include <functional>using namespace std;const int N = 100;bool vis[N];int a[N];int n;int sum, Max;int len;bool input(){scanf("%d", &n);if (n == 0) return false;Max = 0;sum = 0;for (int i = 0; i < n; i++) {scanf("%d", &a[i]);Max = max(Max, a[i]);sum += a[i];}return true;}bool dfs(int complete, int pos, int length){if (complete == n) return true;for (int i = pos; i < n; i++) {if (vis[i]) continue;if (a[i] + length < len) {vis[i] = true;if (dfs(complete + 1, i + 1, a[i] + length)) return true;vis[i] = false;while (a[i] == a[i + 1] && i + 1 < n) i++;if (length == 0) return false;} else if (a[i] + length == len) {vis[i] = true;if (dfs(complete + 1, 0, 0)) return true;vis[i] = false;return false;}}return false;}void solve(){sort(a, a + n, greater<int>());for (len = Max; len <= sum / 2; len++) {if (sum % len == 0) {memset(vis, false, sizeof(vis));if (dfs(0, 0, 0)) {printf("%d\n", len);break;}}}if (len > sum / 2) printf("%d\n", sum);}int main(){#ifndef ONLINE_JUDGEfreopen("d:\\OJ\\uva_in.txt", "r", stdin);#endifwhile (input()) {solve();}return 0;}


0 0
原创粉丝点击