简要题意:
输入两个数n和m,分别表示给你1——n这些整数,将他们按一定顺序摆成一行,按照杨辉三角的计算方式进行求和,求使他们求到最后时结果等于m的排列中字典序最小的一种。
思路分析:
不难推得第一行为n个数a1\a2\……\an时求得的和为i=0∑n-1 ai*(n-1Ci) 根据此公式,考虑到数据量比较小,只需要将原本按递增顺序依次排列好的1——n按next_permutation给出的递增全排列顺序逐个代入,如果结果与m相等就停止循环即可。
参考代码:
1 #include<stdio.h> 2 #include<cstring> 3 #include <iostream> 4 #include <algorithm> 5 using namespace std; 6 typedef long long ll; 7 int fact[11],ncr[11][11],b[10]={1,2,3,4,5,6,7,8,9,10};//先将1——n准备好 8 int main() 9 { 10 int i,j; 11 fact[0]=fact[1]=1;//由于数据小,先预处理,计算好阶乘 12 for(i=2;i<=10;i++) 13 { 14 fact[i]=fact[i-1]*i; 15 } 16 for(i=1;i<=10;i++) 17 { 18 for(j=0;j<=i/2;j++) 19 { 20 ncr[i][j]=ncr[i][i-j]=(fact[i]/(fact[j]*fact[i-j]));//计算各个组合数 21 } 22 } 23 int n,he,de; 24 scanf("%d%d",&n,&he); 25 n--; 26 if(n==0) 27 printf("1\n"); 28 else{ 29 de=0; 30 for(i=0;i<=n;i++)//先判断一下初始递增的情况是否就满足,后面调用next_permutation貌似就直接从第二项开始了 31 { 32 de+=b[i]*ncr[n][i]; 33 } 34 if(de==he) 35 { 36 for(i=0;i<=n;i++) 37 { 38 printf("%d ",b[i]); 39 } 40 return 0; 41 } 42 while(next_permutation(b,b+n+1))//全排列 43 { 44 de=0; 45 for(i=0;i<=n;i++) 46 { 47 de+=b[i]*ncr[n][i]; 48 } 49 if(de==he) 50 { 51 for(i=0;i<=n;i++) 52 { 53 printf("%d ",b[i]); 54 } 55 break; 56 } 57 } 58 printf("\n"); 59 } 60 return 0; 61 }
时间: 2024-10-06 22:34:29