题目大意:给出一系列的数字,在给出一个目标值,要求用+,-,*,/这四种运算符算出目标值并输出表达式,/运算符只有在余数为0时才可以使用

解体思路:暴力DFS破解,通过剪枝来节省时间

1.数的范围要在-32000,32000之间

2.用vis[cur][sum]判断该值的和是否出现过

#include<cstdio>
#include<cstring>

int vis[200][65000];
int num[1000];
int target;
int n;
bool flag;
char sign[1000];

void dfs(int cur, int sum) {

	if(cur == n) {
		if(sum == target) 
			flag = true;
		return ;
	}

	if(sum < -32000 || sum > 32000)
		return ;

	int temp;

	temp = sum + num[cur];
	if(temp >= -32000 && temp <= 32000 && !vis[cur][temp+32000]) {
		vis[cur][temp+32000] = 1;
		sign[cur-1] = '+';
		dfs(cur+1,temp);
		if(flag)
			return ;
	}

	temp = sum - num[cur];
	if(temp >= -32000 && temp <= 32000 && !vis[cur][temp+32000]) {
		vis[cur][temp+32000] = 1;
		sign[cur-1] = '-';
		dfs(cur+1,temp);
		if(flag)
			return ;
	}

	temp = sum * num[cur];
	if(temp >= -32000 && temp <= 32000 && !vis[cur][temp+32000])  {
		vis[cur][temp+32000] = 1;
		sign[cur-1] = '*';
		dfs(cur+1,temp);
		if(flag)
			return ;
	}

	if(sum % num[cur] == 0) {
		temp = sum / num[cur];
		if(temp >= -32000 && temp <= 32000 && !vis[cur][temp+32000]) {
			vis[cur][temp+32000] = 1;
			sign[cur-1] = '/';
			dfs(cur+1,temp);
			if(flag)
				return ;
		}	
	}
	return ;
}

int main() {
	int test;
	scanf("%d", &test);

	while(test--) {

		scanf("%d",&n);
		flag = false;
		memset(vis,0,sizeof(vis));

		for(int i = 0; i < n; i++)
			scanf("%d", &num[i]);

		scanf("%d",&target);
		dfs(1,num[0]);

		if(!flag)
			printf("NO EXPRESSION\n");
		else {
			for(int i = 0; i < n - 1; i++) {
				printf("%d",num[i]);
				printf("%c",sign[i]);
			}	
			printf("%d=%d\n",num[n-1],target);
		}
	}
	return 0;
}