敦煌网站外引流怎么做/微博推广方式有哪些
题目大意:
给出nn根小棒的长度,已知这n根小棒原本由若干根长度相同的长木棒分解而来,求出原棒的最小可能长度。
分析:
直接枚举答案,[maxmax{stickisticki}..长度和],
然后用dfs判断可不可行,
设枚举的答案是xx,
当满足是长度和的约数的时候,
我们则判断能不能合成sum/xsum/x根长木棒,
判断的过程中,我们按照小棒的长度从大到小选择,
然后每次选择的时候,如果当前的木棒长度被用掉了0,那么如果此时不可行,那么这条路就不可行,剪枝
如果你当前的木棒长度中,选择了stickisticki抵消,可是误解,那么你后面选择了和stickisticki相同长度的小棒,那么就是无解,则剪枝
代码:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define N 105using namespace std;int a[N], v[N], n, m;bool cmp(int aa, int bb)
{return aa > bb;
}bool dfs(int tot, int now, int cp, int len)
{if (!tot) return 1;if (now == len) return dfs(tot - 1, 0, 0, len);int dtp = cp;while (dtp < n){dtp++;if (!v[dtp] && now + a[dtp] <= len) {v[dtp] = 1;if (dfs(tot, now + a[dtp], dtp, len)) return 1;v[dtp] = 0;while (a[dtp + 1] == a[dtp] && dtp < n) dtp++;if (now == 0) return 0;}}return 0;
}int main()
{while (~scanf("%d", &m)) {if (!m) break;int Max_num = 0, sum = 0;n = 0;for (int i = 1; i <= m; i++){int x;scanf("%d", &x);if (x <= 50) {a[++n] = x;sum += a[n];Max_num = max(Max_num, a[n]);}}sort(a + 1, a + n + 1, cmp);for (int i = Max_num; i <= sum; i++) if (sum % i == 0){memset(v, 0, sizeof(v));if (dfs(sum / i, 0, 0, i)) {printf("%d\n", i);break;}}}
}