您的位置:首页 > 其它

poj-1011-Sticks-(dfs+剪枝)

2017-08-24 17:36 363 查看

题目地址

http://poj.org/problem?id=1011

题目大意

给出n个小木棒,组合成若干长度最短棍子

解题思路

首先将木棒从大到小排序

dfs(k, l), k是还剩多少木棒没用,l是当前没组装成功的棍子还需多长木棒

剪枝

选取能被木棒总长度能整除的棍子长度

如果当前选取木棒的长度比所需的长度大,剪枝

如果剩余的木棒总长度还没所需的长度大,剪枝

dfs每一次开始选取木棒,要从上一次选取的后面开始

对于相等的木棒,如果一次不成功,就无需再次尝试

Code

#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <queue>
#include <map>
#include <vector>
#include <math.h>
#include <algorithm>
#define INF 0x3fffffff
#define N 80

using namespace std;
typedef long long LL;

int n;
int g_min;

int a
;
int v
;
int L;
int last;
// k is the num of remain sticks
// l is cur need length
bool dfs(int k, int l) {
if (k == 0 && l == 0) {
return true;
}
if (k == 0 && l != 0) {
return false;
}

if (l == 0) {
l = L;
}

// cut
int st = 0;
if (l != L) {
// last : pre used pos
st = last + 1;
}

for (int i = st; i < n; i++) {
if (v[i]) continue;
if (a[i] > l) continue;
// same length
if (i > 0 && v[i-1] == 0 && a[i] == a[i-1]) continue;
// the all remain is not enough
int sum = 0;
for (int j = i; j < n; j++) {
sum += a[j];
}
if (sum < l) {
return false;
}
// dfs
v[i] = 1;
last = i;
if (dfs(k-1, l-a[i])) {
return true;
} else {
v[i] = 0;
// the first staick
// suggest that the len is not good
if (l == L) {
return false;
}
}
}
return false;
}

int main() {

#ifndef ONLINE_JUDGE
freopen("in", "r", stdin);
#else
//
#endif

while (cin >> n) {
if (n == 0) break;
int sum = 0;
for (int i = 0; i < n; i++) {
scanf("%d", &a[i]);
sum +=  a[i];
}
// large is first
sort(a, a+n, greater<int>());
for (L = a[0]; L <= sum/2; L++) {
if ((sum % L) != 0) continue;
memset(v, 0, sizeof(v));
if (dfs(n, L)) {
printf("%d\n", L);
break;
}
}
if (L > sum/2) {
printf("%d\n", sum);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: