题意:
我们把1-n这n个数的某个排列摆成一排,然后相邻两个数的和放到下一行,依此类推,形成一个三角形
3 1 2 4
4 3 6
7 9
16
给你n和最终得到的和k,求第一行的系列(字典序最小)
我们可以发现每个数字的计算次数是一个杨辉三角
1 1
1 2 1
1 3 3 1
1 4 6 4 1
......
所以我们只要枚举1-n的全排列,计算sum{ans[i]*c(i-1,n-1)}是否为K就行了
当然从顶层一步一步算到最低也是一样的
10!为380W,而且因为左右对称,规模能减一半
枚举全排序能用STL中的next_permutation能很方便的求出
如果不知道这个函数,就写个DFS
//#pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<iostream> #include<sstream> #include<cmath> #include<climits> #include<string> #include<map> #include<queue> #include<vector> #include<stack> #include<set> using namespace std; typedef long long ll; typedef pair<int,int> pii; #define pb(a) push_back(a) #define INF 0x1f1f1f1f #define lson idx<<1,l,mid #define rson idx<<1|1,mid+1,r #define PI 3.1415926535898 void debug() { #ifdef ONLINE_JUDGE #else freopen("d:\in.txt","r",stdin); // freopen("d:\out1.txt","w",stdout); #endif } char getch() { char ch; while((ch=getchar())!=EOF) { if(ch!=' '&&ch!=' ')return ch; } return EOF; } int cc(int m,int n) { int k=1; for(int i=0;i<n;i++) k*=(m-i); for(int i=1;i<=n;i++) k/=i; return k; } int c[11][11]; int n,k; int ans[11]; int main() { for(int i=1;i<=10;i++) //预处理出全部C(n,i),只是在追求速度,可以不必 for(int j=0;j<=i;j++) c[i][j]=cc(i,j); while(scanf("%d%d",&n,&k)!=EOF) { for(int i=1;i<=n;i++)ans[i]=i; do { int sum=0; for(int i=1;i<=n;i++) sum+=ans[i]*c[n-1][i-1]; if(sum==k)break; }while(next_permutation(ans+1,ans+1+n)); for(int i=1;i<=n;i++) printf("%d%c",ans[i],i==n?' ':' '); } return 0; }