A decorative fence(Poj1037)

The length from the N-1 to N blocks of wood surrounded by a fence. Fence requirement is undulated, i.e. each board or both sides of the board than it was low (lower) than either of its sides are higher board (high). Now sort all arrangements to meet the requirements. Collation is calculated from the first piece of wood, the shorter the ranking Echizen, equal to the previous, relatively backward turn. (I.e. lexicographic order) is given first and a specified number N m, the m-th seek compliance with the requirements of the arrangement.
Input: The first line indicates the number of test cases a positive integer. Each row took a test case containing two numbers m and N represent, respectively.
Output: wood specified permutation scheme. As shown for the case where n = 4 for all of
the Sample the Input
2
2. 1
. 3. 3                                                                       

Sample Output
1 2 
2 3 1

 

First, similar to the multiplier optimization dp, we try to fill by law to determine rankings for the wood fence length c.
First, we can enumerate the length of the first block of wood, to H, the total n-1 program plank back configuration number t,
if t> = c, then the first block of wood to length is h, continue to try to determine the length of the second block of wood, or c- = t, h is incremented by 1 to repeat the above determination.
What, then (so so) we can find the answer, we now need to pre-treatment values of t

Set F [i, j, k] indicates a block length i construct different board fence, the leftmost board from small to large j-th bit, which is the state k (k is 0 for low, k is 1 showing high)

f[i,j,0]=∑p=j~i-1f[i-1,p,1]
f[i,j,1]=∑p=1~j-1f[i-1,p,0]

 

long long f[21][21][2],m;
bool used[21];
void prepare()
{
    int i,j,k;
    f[1][1][0]=f[1][1][1]=1;
    for(i=2;i<=20;i++)
      for(j=1;j<=i;j++)
      {
           for(k=j;k<=i-1;k++)f[i][j][0]+=f[i-1][k][1];
           for(k=1;k<=j-1;k++)f[i][j][1]+=f[i-1][k][0];
      }
}

 

To fill the next start test, referred Last long piece of wood, a height position of the K,
1: K ^ = 1;
2: Enumeration of length len i, judgment, identify the determined len
. 3: I plus 1, repeat steps

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std;
long long f[21][21][2],m;
bool used[21];
void prepare()
{
    int i,j,k;
    f[1][1][0]=f[1][1][1]=1;
    for(i=2;i<=20;i++)
      for(j=1;j<=i;j++)
      {
           for(k=j;k<=i-1;k++)f[i][j][0]+=f[i-1][k][1];
           for(k=1;k<=j-1;k++)f[i][j][1]+=f[i-1][k][0];
      }
}
int main()
{
    int t,n,i,j,k,last,len;
    scanf("%d",&t);
    prepare();
    while(t--)
    {
        scanf("%d%lld",&n,&m);
        memset(used,0,sizeof(used));
        for(j=1;j<=n;j++)//第一块木板单独处理 
        {
            if(f[n][j][1]>=m)
            {
                last=j;k=1;
                break;
            }
            else m-=f[n][j][1];
            if(f[n][j][0]>=m)
            {
                last=j;k=0;
                break;
            }
            else m-=f[n][j][0];
        }
        used[last]=1;printf("%d ",last);
        for(i=2;i<=n;i++)
        {
            k^=1;j=0;
            for(len=1;len<=n;len++)
            {
                if(used[len])continue;
                j++;
                if((k==0&&len<last)||(k==1&&len>last))//合法性 
                {
                    if(f[n-i+1][j][k]>=m){last=len;break;}
                    else m-=f[n-i+1][j][k];
                }
            }
            used[last]=1;
            printf("%d ",last);
        }
        puts("");
    }
    return 0;
}

 

 

 



Guess you like

Origin www.cnblogs.com/dsb-y/p/11200593.html