Codeforces 553B Kyoya and Permutation

Let's define the permutation of length n as an array p = [p1, p2, ..., pn] consisting of n distinct integers from range from 1 to n. We say that this permutation maps value 1 into the value p1, value 2 into the value p2 and so on.

Kyota Ootori has just learned about cyclic representation of a permutation. A cycle is a sequence of numbers such that each element of this sequence is being mapped into the next element of this sequence (and the last element of the cycle is being mapped into the first element of the cycle). The cyclic representation is a representation of p as a collection of cycles forming p. For example, permutationp = [4, 1, 6, 2, 5, 3] has a cyclic representation that looks like (142)(36)(5) because 1 is replaced by 4, 4 is replaced by 2, 2 is replaced by 1, 3 and 6 are swapped, and 5 remains in place.

Permutation may have several cyclic representations, so Kyoya defines the standard cyclic representation of a permutation as follows. First, reorder the elements within each cycle so the largest element is first. Then, reorder all of the cycles so they are sorted by their first element. For our example above, the standard cyclic representation of [4, 1, 6, 2, 5, 3] is (421)(5)(63).

Now, Kyoya notices that if we drop the parenthesis in the standard cyclic representation, we get another permutation! For instance,[4, 1, 6, 2, 5, 3] will become [4, 2, 1, 5, 6, 3].

Kyoya notices that some permutations don't change after applying operation described above at all. He wrote all permutations of length nthat do not change in a list in lexicographic order. Unfortunately, his friend Tamaki Suoh lost this list. Kyoya wishes to reproduce the list and he needs your help. Given the integers n and k, print the permutation that was k-th on Kyoya's list.

Input

The first line will contain two integers nk (1 ≤ n ≤ 501 ≤ k ≤ min{1018, l} where l is the length of the Kyoya's list).

Output

Print n space-separated integers, representing the permutation that is the answer for the question.

Sample test(s)
input
4 3
output
1 3 2 4
input
10 1
output
1 2 3 4 5 6 7 8 9 10

解题思路:首先应该弄清楚题目中standard cyclic representation 中只有当交换相邻位置的两个元素或者不交换两种情况是满足要求的。因此对于长度为n的序列排列中是standard cyclic representation的种类数为dp[n],则不难得出递推式dp[n]=dp[n-1]+dp[n-2],则题目要求求解第k小的方案,我们可以根据这个dp[]序列的数值进行构造,反正我是照着第一个例子比划着然后找出答案的。
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef long long ll;
const int maxn = 55;
ll  num[maxn];
int arr[maxn];

void init() {
    num[0] = num[1] = 1;
    for(int i = 2; i <= 50; ++i) {
        num[i] = num[i-1] + num[i-2];
    }
}

int main() {

    init();
    int n;
    ll k;
    int id = 1;
    cin >> n >> k;
    while(num[id] < k) id++;
    for(int i = n; i > id; --i) {
        arr[n-i+1] = n - i + 1;
    }
    while(k) {
        if(num[id] == k) {
            for(int i = id; i > 0; i -=2) {
                if(i - 1 > 0) {
                    arr[n-i+1] = n-i+2;
                    arr[n-i+2] = n-i+1;
                } else {
                    arr[n-i+1] = n-i+1;
                }
            }
            break;
        } else {
            k -= num[id-1];
            arr[n-id+1] = n-id+2;
            arr[n-id+2] = n-id+1;
            id -= 2;
            while(id > 0 && k <= num[id]) {
                arr[n-id+1] = n - id + 1;
                id--;
            }
            id++;
        }
    }
    for(int i = 1; i <= n; ++i) {
        if(i == 1) {
            printf("%d", arr[i]);
        } else {
            printf(" %d", arr[i]);
        }
    }
    printf("\n");
    return 0;
}


你可能感兴趣的:(Codeforces)