A decorative fence

A decorative fence

In \ (1 \ sim n \) full array \ (\ {a_i \} \ ) , only the size of the interleaved (i.e., any position i satisfies \ (a_ {i-1} <a_i> a_ {i + 1 I-ORA_. 1 {}}> a_i <A_. 1} + I {\) ) permutation scheme is legitimate, valid interrogation whole arrangement scheme of the c-th, \ (n-\ Leq 20 is, c \ ^ {2 Leq 63} \) .

solution

First, find the first of several programs, try to use natural methods to fill, but the problem is different from the general arrangement of recurrence, because a number is placed in a position that can not be put in, but noted that the arrangement of a nature, that is, pay attention size, and it would therefore be considered discrete recursive.

To try to fill in, what is the most natural expression left to fill, but also show the length of the sequence, in order to safeguard the legitimate sequence, may wish to far left \ (a_i> a_ {i + 1} \) in mind to do, otherwise denoted 0, set \ (F [i] [j] [k] \) represents the length of the i arrangement, the left-most atoms of a large number of j, k is the state of the program number, has difficult

\[f[i][j][0]=\sum_{k=j}^{i-1}f[i-1][k][1]\]
\[f[i][j][1]=\sum_{k=1}^{j-1}f[i-1][k][0]\]

Border: \ (F [. 1] [. 1] [0] = F [. 1] [. 1] [. 1] =. 1 \) , the remainder being 0

So we can directly use the program the number of small to large test fill, note that the first position of the state in 1, can be 0, 1 to fill priority.

Reference Code:

#include <iostream>
#include <cstdio>
#include <cstring>
#define il inline
#define ri register
#define ll long long
using namespace std;
bool used[21];
ll dp[21][21][2];
il void prepare();
int main(){
    int lsy;scanf("%d",&lsy),prepare();
    while(lsy--){
        int n,last;bool p;ll c;
        memset(used,0,sizeof(used));
        scanf("%d%lld",&n,&c);
        for(int i(1);i<=n;++i){
            if(dp[n][i][1]>=c){
                last=i,p=1;
                break;
            }
            else c-=dp[n][i][1];
            if(dp[n][i][0]>=c){
                last=i,p=0;
                break;
            }
            else c-=dp[n][i][0];
        }printf("%d ",last),used[last]|=true;
        for(int i(2),j,k;i<=n;++i){
            p^=true;
            for(j=1,k=0;j<=n;++j){
                if(used[j])continue;++k;
                if((p&&j>last)||(!p&&j<last))
                    if(dp[n-i+1][k][p]>=c){
                        last=j,used[j]|=true;
                        break;
                    }
                    else c-=dp[n-i+1][k][p];
            }printf("%d ",last);
        }putchar('\n');
    }
    return 0;
}
il void prepare(){
    dp[1][1][0]=dp[1][1][1]=1;
    for(int i(2),j,k;i<=20;++i)
        for(j=1;j<=i;++j){
            for(k=j;k<i;++k)dp[i][j][0]+=dp[i-1][k][1];
            for(k=1;k<j;++k)dp[i][j][1]+=dp[i-1][k][0];
        }
}

Guess you like

Origin www.cnblogs.com/a1b3c7d9/p/10987954.html