This question is still hard to come up with. I had to understand it for a long time, and I had to figure it out after I asked Daniel. Instead, I think the black book is not clear. Now let's take a look at the specific ideas of this question.

Let's look at a qualified sequence, such as a sequence with a length of n. When we determine the first K items, the remaining n-k items have a one-to-one relationship with the qualified sequence from 1 to n-k. This is why we use dynamic planning, and there are overlapping sub-problems. The following States are defined:

DP [I] [J] [0] indicates the total number of valid sequences starting with I and whose length is J.

DP [I] [J] [1] indicates the total number of valid sequences starting with I and whose length is J.

The subproblem of the current sequence with the length of J exactly corresponds to the valid sequence of the length of the J-1 (which needs to be understood carefully ), so we can determine the definition of our status and the validity of the transfer.

DP [I] [J] [0] = sum {DP [x] [J-1] [1]} (J-1> = x> = I)

DP [I] [J] [1] = sum {DP [x] [J-1] [0]} (I> x> = 1)

After the preceding Dp value is pre-processed, it is the constructor.

For this sort of structure, we usually subtract the number of valid orders determined by the high position by bit. The same is true for this question, but we have to deal with it in a special way to determine whether it is going to rise or fall. Then, the number of matching orders is subtracted, and each bit is determined at a time.

At the end of the output solution, we should note that we store the largest number in the remaining optional number, so we need to reverse map the number between 1-N, the data volume is relatively small, and the enumeration is violent.

The idea is like this. If you don't understand it, you can look at the Code:

#include <iostream>#include <cstring>#include <cstdlib>#include <cstdio>using namespace std;const int Max=25;typedef long long LL;LL dp[Max][Max][2];void init(int n){ memset(dp,0,sizeof(dp)); dp[1][1][0]=1;//up dp[1][1][1]=1;//down for(int j=2;j<=n;j++) { for(int i=1;i<=j;i++) { for(int x=i;x<j;x++) { dp[i][j][0]+=dp[x][j-1][1]; } for(int x=1;x<i;x++) { dp[i][j][1]+=dp[x][j-1][0]; } } }}int ans[Max];void solve(int n,LL c){ int tn=n; int flag,cur; LL sum=0LL; for(int i=1;i<=n;i++) { if(sum+dp[i][n][0]+dp[i][n][1]>=c) { ans[1]=i; c-=sum; cur=i; break; } sum+=(dp[i][n][0]+dp[i][n][1]); } if(c<=dp[cur][n][1]) flag=1; else{c-=dp[cur][n][1];flag=0;} --n; int len=2; while(n>0) { if(flag==0) { for(int i=cur;i<=n;i++) { if(dp[i][n][1]>=c) { cur=i; ans[len++]=cur; break; } c-=dp[i][n][1]; } } else { for(int i=1;i<cur;i++) { if(dp[i][n][0]>=c) { cur=i; ans[len++]=cur; break; } c-=dp[i][n][0]; } } --n; flag=1-flag; } int vis[Max]={0}; for(int i=1;i<=tn;i++) { for(int j=1;j<=tn;j++) { if(vis[j]==0) { ans[i]--; if(ans[i]==0) { printf("%d%c",j,i==tn?'\n':' '); vis[j]=1; break; } } } }}int main(){ int T,n; LL c; scanf("%d",&T); init(20); while(T--) { scanf("%d %lld",&n,&c); solve(n,c); } return 0;}