杨辉三角一图览 			  			1  					1 		1  				1 		2       1  			1        3 	    3       1  		1 		4 		6 		4  		1  	1 		5 		10 		10 		5 		1  1 		6 		15 		20 		15 		6 		1 
前言 由图可知杨辉三角具有对称性,很多时候可以折半计算,节省时间
 
借个图先
求杨辉三角任意一行 我们在编程界中经常把排列组合中的公式用A(a,b),C(a,b)表示
 
 又根据杨辉三角的对称性,我们可以折半计算,在计算中心轴左边的值的同时也能将右边的值算出来
该公式的应用lP1118 [USACO06FEB]Backward Digit Sums G/S 
代码
#include  <iostream>  using  namespace  std;const  int  N = 30 ;int  n,sum;bool  st[N];int  a[N];int  delta[N];void  getdelta () 	delta[0 ] = delta[n-1 ] = 1 ; 	 	if (n > 1 ) 	{ 		for (int  i = 1 ;i*2  <= n;++i) 			delta[i] = delta[n-i-1 ] = (n-i) * delta[i-1 ]/i; 	} }  bool  dfs (int  u,int  num,int  v) 	if (v > sum) return  false ; 	 	if (u == n) 	{ 		if (v == sum) 		{ 			a[u] = num; 			return  true ; 		} 		return  false ; 	} 	 	st[num] = true ; 	 	for (int  i = 1 ;i <= n;++i) 	{ 		if (!st[i] && dfs (u + 1 ,i,v + delta[u] * i)) 		{ 			a[u] = num; 			return  true ; 		} 	} 	st[num] = false ; 	 	return  false ; } int  main () 	cin>>n>>sum; 	 	getdelta (); 	 	if (dfs (0 ,0 ,0 )) for (int  i = 1 ;i <= n;++i) cout<<a[i]<<' ' ; 	 	return  0 ; } 
求杨辉三角某一值起始位置 经过多数人的研究,已经找到了一种非常精妙的方法来快速确定任意值的起始位置,所耗时间只需4ms
 
首先再看一次图
			  			1  					1 		1  				1 		2       1  			1        3 	    3       1  		1 		4 		6 		4  		1  	1 		5 		10 		10 		5 		1  1 		6 		15 		20 		15 		6 		1 
我们可以将杨辉三角的右半边删掉,因为杨辉三角的对称性,显而易见我们能推导出任意值的起始位置一定在左半边
			  			1  					1 		 				1 		2        			1        3 	     		1 		4 		6 		 	1 		5 		10 	 1 		6 		15 		20 	
得到该图后我们发现,我们可以通过斜行位置与行位置来确定某一值
  long  long  C (int  a, int  b)   	long  long  res = 1 ; 	for  (int  i = a, j = 1 ;j <= b;--i, ++j) 	{ 			res = res * i / j; 	} 	return  res; }   
同时我们可以确定,这一斜行找到的值的位置,总会比他上面一个斜行找到同一值的位置要小
而且每一斜行k的起始行数n,总有一种规律 2*k = n
现在我们总结一下前面找到的规律
pos  = (n + 1 )*n / 2  + k +1 ;
例题P8749 [蓝桥杯 2021 省 B] 杨辉三角形 
#include  <iostream>  using  namespace  std;long  long  n;long  long  C (int  a, int  b)  	long  long  res = 1 ; 	for  (int  i = a, j = 1 ;j <= b;--i, ++j) 	{ 		res = res * i / j; 		if  (res > n) return  res; 	} 	return  res; } int  main () 	cin >> n; 	if  (n == 1 ) 	{ 		cout << 1  << endl; 		return  0 ; 	} 	for  (int  i = 16 ;i >= 1 ;--i) 	{ 		long  long  l = 2  * i, r = max (l, n); 		while  (l < r) 		{ 			long  long  mid = (l + r) >> 1 ; 			if  (C (mid, i) < n) l = mid + 1 ; 			else  r = mid; 		} 		if  (C (l, i) == n) 		{ 			cout << (l + 1 ) * l / 2  + i + 1  << endl; 			return  0 ; 		} 	} 	return  0 ; }