您的位置:首页 > 其它

POJ 1011: Sticks

2012-08-21 03:15 190 查看
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <string>

int first (int A[], int B[], int size) {
for (int i = 1; i <= size; ++ i) {
if (B[i] == 0) {
B[i] = 1;
return i;
}
}
return 0;
}

int find (int A[], int B[], int size, int groupnum, int ith, int sum) {
if (groupnum == ith) {
return 1;
}
for (int i = 1; i <= size; ++ i) {
if (B[i] == 0 && (sum + A[i]) < A[0]) {
B[i] = 1;
if (find (A, B, size, groupnum, ith, sum + A[i]))
return 1;
else
B[i] = 0;
}
if (B[i] == 0 && (sum + A[i]) == A[0]) {
B[i] = 1;
int t = first(A, B, size);
if (find (A, B, size, groupnum, ith + 1, A[t]))
return 1;
else {
B[i] = 0;
B[t] = 0;
return 0;
}

}
if (sum == A[0]) {
int t = first(A, B, size);
if (find(A, B, size, groupnum, ith + 1, A[t]))
return 1;
else {
B[t] = 0;
return 0;
}
}
}
return 0;
}

int go(int A[], int B[], int size, int groupnum) {
return 0;
}

void swap (int &a, int &b) {
if (a == b) return;
a ^= b ^= a ^= b;
}

int partition (int A[], int p, int r) {
int q = p;
for (int i = p + 1; i <= r; ++ i) {
if (A[i] > A[p]) {
++ q;
swap (A[q], A[i]);
}
}
swap(A[q], A[p]);
return q;
}

void qsort (int A[], int p, int r) {
while (p < r) {
int q = partition(A, p, r);
qsort(A, p, q - 1);
p = q + 1;
}
}

int main () {
int n = 0;
scanf ("%d", &n);
while (n) {
int A[n + 1];
int B[n + 1];
memset (B, 0, sizeof (B));
int sum = 0;
for (int i = 1; i <= n; ++ i) {
scanf ("%d", &A[i]);
sum += A[i];
}
qsort (A, 1, n);
for (int i = sum / A[1]; i >= 1; -- i) {
if (sum % i == 0) {
memset(B, 0, sizeof(B));
A[0] = sum / i;
if ( find(A, B, n, i, 1, A[first(A, B, n)]) ) {printf("%d\n", A[0]);
break;
}
}
}
scanf ("%d", &n);
}
return 0;
}


经典深搜+剪枝

简单来讲就是穷举,但有很多地方可以优化。

1:只需考虑1到(sum / max)个组(循环是反过来写的,因为要求最短)

2: 进行排序

3: 假如有n个组,搜完n-1个组就可以了

。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: