【DFS】XIII Open Championship of Y.Kupala Grodno SU Grodno, Saturday, April 29, 2017 Problem D. Divisibility Game

【DFS】XIII Open Championship of Y.Kupala Grodno SU Grodno, Saturday, April 29, 2017 Problem D. Divisibility Game

题意:给你一个序列,长度不超过52,每个元素不超过13。让你重新对这个序列排序,sum(i)表示i的前缀和,使得排序过后,对每个i,都有sum(i)%i==0。

深搜,加两个优化:①倒着从后向前搜;②枚举的时候不要枚举52个,而枚举值域(只有13),能快一点。

另外,一开始想的是相同的元素在最后一定都相邻,但是事实上试了试之后发现不行。

#include<cstdio>
#include<cstdlib>
using namespace std;
int path[60],a[60],n,cnt[15];
void dfs(int cur,int sum){
	if(cur>n){
		for(int i=n;i>1;--i){
			printf("%d ",path[i]);
		}
		printf("%d
",path[1]);
		exit(0);
	}
	for(int i=1;i<=13;++i){
		if(cnt[i] && sum%i==0){
			--cnt[i];
			path[cur]=i;
			dfs(cur+1,sum-i);
			++cnt[i];
		}
	}
}
int main(){
//	freopen("d.in","r",stdin);
	int sum=0;
	scanf("%d",&n);
	for(int i=1;i<=n;++i){
		scanf("%d",&a[i]);
		++cnt[a[i]];
		sum+=a[i];
	}
	dfs(1,sum);
	puts("-1");
	return 0;
}