2.9 算法一题

DFS

数字游戏

本题思路不难想,就是将1-n的所有数字的全排列枚举出来,因为数字序列添加的方法已经给出了,找出其中规律即可得到合并数列的公式。然后把每个数列合并后的结果跟目标值比较

思路以及代码

2.9 算法一题_第1张图片

/*
给定一个1~N的排列a[i],每次将相邻两个数相加,得到新序列,再对新序列重复这样的操作,
显然每次得到的序列都比上一次的序列长度少1,最终只剩一个数字。
例如:
3 1 2 4
4 3 6
7 9
16
现在如果知道N和最后得到的数字sum,请求出最初序列a[i],
为1~N的一个排列。若有多种答案,则输出字典序最小的那一个。数据保证有解。

样例输入
4 16
样例输出
3 1 2 4
数据规模和约定
0



#include

using namespace std;

const int N=12;

int a[N];
int n,sum;
int p[N];//用于判断某个元素是否被用过 
int get_a=0;

int c_nm(int n,int m){
	//求组合数 
	int fenzi=1;
	int fenmu1=1;
	int fenmu2=1;
	
	for(int i=1;i<=n;i++)
		fenzi*=i;
	
	for(int i=1;i<=m;i++)
		fenmu1*=i;
		
	for(int i=1;i<=(n-m);i++)
		fenmu2*=i;
		
	return fenzi/(fenmu1*fenmu2);		
		
}

int  judge(int a[]){
	//给出数组a[] 
	int tot=0;
	for(int i=1;i<=n;i++){
		tot+=c_nm(n-1,i-1)*a[i];
	}
	if(tot==sum)
		return 1;
	else
		return 0;
}


void dfs(int layer,int a[]){
	//层数layer用于判断是否数字有n个
	//a[]数组存储可能的答案 
	if(layer==n+1){
		if(judge(a)){
			for(int i=1;i<=n;i++){
				cout<<a[i]<<" ";
			}
			get_a=1;//说明得到答案 
			return ;	
		}
		return ;
	}
	
	for(int i=1;i<=n;i++){
		if(get_a)
			return ;
			
		if(p[i]==0){//某个元素没有被使用过 
			a[layer]=i;
			p[i]=1;
			dfs(layer+1,a);
			p[i]=0; 
		}
	}
} 


int main(){
	cin>>n>>sum;
	dfs(1,a);
	return 0;
}

你可能感兴趣的:(算法,深度优先,leetcode)