该题问给定的棍子能否组成一个正方形。首先我们要判定是否总长度是4的倍数,然后再决定是否存在某条边大于组合边长。
搜索的过程中也是可以进行剪枝了。
首先将边排序,我们可以假定所有的组合边由大小递减的边组成,那么我们在搜索的时候就不用再往前找边了。
其次我们可以确定任何一条边都一定在一条组合边中,那么当我们以任意一条边开搜的情况下无解的话,那么我们就可以直接返回no了。
最后在搜索某条边无解的情况下,我们可以把相同大小的边略过,因为前面相同长度的边都无法安排出一种方案,在少一条相同边情况下肯定也就无法给出安排了。
代码如下:
#include <cstdlib> #include <cstdio> #include <cstring> #include <algorithm> using namespace std;int N, seq[25], use[25], mode;bool dfs(int cap, int last, int num) {if (num == N) {return true;}if (cap == 0) {if (dfs(mode, N+1, num)) {return true;}else {return false;}}else {for (int i = last-1; i >= 1; --i) {if (cap >= seq[i] && !use[i]) {use[i] = 1;if (dfs(cap-seq[i], i, num + 1)) {return true;}else {use[i] = 0;if (i == N) {return false;}while (seq[i-1] == seq[i]) --i;} }}}return false; }int main() {int T, sum, Max;scanf("%d", &T);while (T--) {sum = 0, Max = -1;memset(use, 0, sizeof (use));scanf("%d", &N);for (int i = 1; i <= N; ++i) {scanf("%d", &seq[i]);Max = max(Max, seq[i]);sum += seq[i];}if (sum % 4 != 0 || Max > sum / 4) {puts("no");continue;}sort(seq+1, seq+N+1);mode = sum / 4; // 每一边的大小printf(dfs(mode, N+1, 0) ? "yes\n" : "no\n");}return 0; }