POJ 2362(Square-搜索剪枝1-相对顺序)

Language:
Square
Time Limit: 3000MS   Memory Limit: 65536K
Total Submissions: 17066   Accepted: 5878

Description

Given a set of sticks of various lengths, is it possible to join them end-to-end to form a square?

Input

The first line of input contains N, the number of test cases. Each test case begins with an integer 4 <= M <= 20, the number of sticks. M integers follow; each gives the length of a stick – an integer between 1 and 10,000.

Output

For each case, output a line containing “yes” if is is possible to form a square; otherwise output “no”.

Sample Input

3
4 1 1 1 1
5 10 20 30 40 50
8 1 7 2 6 4 4 3 5

Sample Output

yes
no
yes

Source

《搜索是怎样剪枝的-1》

1.只要找到3条边。

2.从大到小顺序找。

3.每次搜边时要确定边的相对顺序唯一(直接从TLE→秒)


#include<cstdio>

include<cstdlib>

include<algorithm>

include<functional>

include<cstring>

include<iostream>

using namespace std;

define MAXM (20+10)

int tt,n,a[MAXM],cnt,len; bool b[MAXM],flag; bool dfs(int l,int x,int pre) { // cout<<l<<' '<<x<<' '<<kth<<endl; if (x==len) {l++;x=0;pre=n-1;} if (l==4) { return 1; } for(int i=pre-1;i;i--)
if (!b[i]&&x+a[i]<=len) { b[i]=1; if (dfs(l,x+a[i],i)) return 1; b[i]=0; // if (!x) return 0; } return 0; } int main() { scanf("%d",&tt); while (tt--) { cnt=0; scanf("%d",&n); for (int i=1;i<=n;i++) { scanf("%d",&a[i]); cnt+=a[i];b[i]=0; } sort(a+1,a+1+n); if (n<4||cnt%4||a[n]>cnt/4) { printf("no\n");continue; } b[n]=1;len=cnt/4; if (dfs(1,a[n],n)) { printf("yes\n"); } else printf("no\n"); }
return 0; }