小记:这题看重的是剪枝,但是都后来发现,其实这应该是一个当初的想法错误,导致的TLE


思路:dfs,一条边一条边的dfs,当能dfs出3条边时,就是yes。当然最开始应该判断%4是否等于0对于总长度。

而dfs的顺序就是从大到小,这点算是剪枝吧,可以少很多工作。

当没组成一条边时,就从大到小搜,一直往小的搜,

而当组成了一条边的时候就要从头开始搜。因为没组成时,可能出现加起来大于一条边的长度的。


我之前wa就出错在没组成一条边,我也是从头开始搜,唉~愚钝!


代码:

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <map>
#include <set>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>

using namespace std;

#define mst(a,b) memset(a,b,sizeof(a))
#define REP(a,b,c) for(int a = b; a < c; ++a)
#define eps 10e-8

const int MAX_ = 1010;
const int N = 100010;
const int INF = 0x7fffffff;

int C[MAX_];
char str[MAX_][MAX_];
int a[MAX_];
int vis[MAX_];

int n, m, avg;

int dir[4][2] = {{0,-1},{-1,0},{0,1},{1,0}};
int dfs(int sum[], int x)
{

    bool flag = 0;
    REP(i, 0, 4){
        if(sum[i] != avg){flag = 1;break;}
    }
    if(!flag) return 1;

    if(x >= n)return 0;

    flag = 0;
    int i = x;
    //REP(i, x, n){
        if(!vis[i]){
            REP(j, 0, 4){
                if(sum[j] + a[i] <= avg ){
                    if(sum[j] == 0 && flag)continue;
                    sum[j] += a[i];
                    int tmp = dfs(sum, x+1);
                    if(tmp)return 1;
                    sum[j] -= a[i];
                    if(sum[j] == 0)flag = 1;
                }
            }
        }
    //}
    return 0;
}


int dfs1(int sum, int x,int cur)
{
    if(x == 3)return 1;
    //printf("%d %d ok\n",sum, x);
    REP(i, cur, n){
        if(!vis[i]){

            if(sum + a[i] == avg){
                vis[i] = 1;
                int tmp = dfs1(0, x+1, 0);
                if(tmp == 1)return 1;
                vis[i] = 0;
            }
            else if(sum + a[i] < avg){
                vis[i] = 1;
                int tmp = dfs1(sum + a[i], x, i);
                if(tmp == 1) return 1;
                vis[i] = 0;
            }
        }
    }
    return 0;
}

bool cmp(const int a, const int b)
{
    return a > b;
}

int main()
{
    int T;
    scanf("%d", &T);
    while(T-- &&scanf("%d", &n)){
        int sum = 0;
        REP(i, 0, n){
            scanf("%d",&a[i]);
            sum += a[i];
        }
        sort(a, a+n, cmp);
        if(sum%4 != 0 || n < 4 || a[0] > sum/4){
            printf("no\n");
            continue;
        }
        avg = sum/4;
        mst(vis, 0);
        int ss[4];
        mst(ss, 0);

        int ans = dfs1(0, 0, 0);//(ss, 0);

        if(ans){
            printf("yes\n");
        }else {
            printf("no\n");
        }

    }
	return 0;
}