链接
题解
用 f i f_i fi表示 i i i个数的排列符合条件的方案数,则 f i = f i − 1 + f i − 2 f_i=f_{i-1}+f_{i-2} fi=fi−1+fi−2
然后贪心填一填就行了
代码
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define iinf 0x3f3f3f3f
#define linf (1ll<<60)
#define eps 1e-8
#define maxn 1000010
#define cl(x) memset(x,0,sizeof(x))
#define rep(_,__) for(_=1;_<=(__);_++)
#define em(x) emplace(x)
#define emb(x) emplace_back(x)
#define emf(x) emplace_front(x)
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
ll read(ll x=0)
{
ll c, f(1);
for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-f;
for(;isdigit(c);c=getchar())x=x*10+c-0x30;
return f*x;
}
ll f[60], n, k, ans[60];
int main()
{
ll i, j;
n=read(), k=read();
f[1]=1, f[2]=2;
for(i=3;i<=50;i++)f[i]=f[i-1]+f[i-2];
for(i=1;i<=50;i++)ans[i]=i;
for(i=1;i<n;)
{
if(k>f[n-i])
{
swap(ans[i],ans[i+1]);
k-=f[n-i];
i+=2;
}
else
{
i+=1;
}
}
rep(i,n)printf("%lld ",ans[i]);
return 0;
}