Codeforces 513B2 - Permutations (思维)

题意

P为一个序列。

定义 F(p)=ni=1nj=imin(pi,pi+1,...,pj)

现在要求输出所有满足F(n)最大的序列中字典序第k大的序列。

思路

先求出怎样的序列能满足F(p)最大。

假设现在是一个空的序列,那么1是最小的元素,它只能被放在序列的最前面或者最后面。因为如果放在中间产生的结果必定小。

之后考虑2,也和1一样。把1填的那个位置去除之后2也只能放在剩下来的最前面或者最后面。以此类推。

所以总共合法的排列有 2n1 个。

接下来考虑字典序。

当放1时,如果放第一个,那么剩下来的可能数是 2n11 ,当k大于这个数时,显然1放前面无法到达第k大字典序。所以这时候要放后面。

剩下来的排列数其实就是 2nnum1

以此类推。把1放后面之后减去1放前面能得到的情况,然后考虑2。和考虑1是一样的。

代码

int vis[100];
vector<int> ans;

int main()
{
    LL n, k;
    cin >> n >> k;
    int pos = 1;
    for (int i = 0; i < n; i++)
        for (; pos <= n; pos++)
        {
            if (k > (1ll<<(n-pos-1))) k -= (1ll<<(n-pos-1));
            else
            {
                vis[pos] = 1;
                ans.PB(pos);
                pos++;
                break;
            }
        }
    for (int i = n; i >= 1; i--)
    {
        if (vis[i]) continue;
        ans.PB(i);
    }
    for (auto i: ans) printf("%d ", i);
    return 0;
}

你可能感兴趣的:(ACM)