【洛谷三月月赛R2】小清新签到题

40 篇文章 0 订阅

题目描述

题目还是简单一点好。

给定自然数n、k、x,你要求出第k小的长度为n的逆序对对数为x的1~n的排列,然后用仙人图上在线分支定界启发式带花树上下界最小费用流解决问题,保证存在。

注:逆序对为满足、的。比较为字典序比较,即比较从前往后第一个不同的位置。第k小从1开始标号。一个1~n的排列定义为一个长度为n的数列,排序完可以得到1~n。

输入输出格式

输入格式:
一行三个自然数n、k、x。

输出格式:
输出满足条件的排列,一行n个数,用空格分隔。

输入输出样例

输入样例#1:
3 2 2
输出样例#1:
3 1 2
输入样例#2:
10 6 4
输出样例#2:
1 2 3 4 5 7 6 10 9 8
输入样例#3:
50 233 233
输出样例#3:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 32 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 33 35 34 31 30 29 28
输入样例#4:
50 233333333 333
输出样例#4:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 43 49 50 47 46 45 48 44 41 42 40 39 37 38 36 35 34 33 32 30 29 31 28 25 26 27 24
说明

对于10%的数据,这里写图片描述

对于30%的数据,这里写图片描述

对于50%的数据,这里写图片描述

对于另外20%的数据,这里写图片描述

对于100%的数据,这里写图片描述这里写图片描述,保证存在符合题意的排列。

题解
参见官方题解

代码

#include<cstdio>
#include<string>
#include<iostream>
#define inf 10000000000001
#define ll long long
ll sum[2][45000],f[305][45000];
int ans[305];
bool vis[305];
int n,x;
ll k;
using namespace std;
int main()
{
    cin>>n>>k>>x;
    f[1][0]=1;sum[1][0]=1;sum[1][1]=1;
    for (int i=2;i<=n;i++)
    {
        for (int j=0;j<=i*(i-1)/2;j++)
        {
            if (j>=i) f[i][j]=sum[(i&1)^1][j]-sum[(i&1)^1][j-i]; else f[i][j]=sum[(i&1)^1][j];
            if (f[i][j]>=inf) f[i][j]=inf;
        }
        for (int j=0;j<=i*(i+1)/2;j++)
            sum[i&1][j]= (j ? sum[i&1][j - 1] : 0) + f[i][j];
    }
    for (int p=1;p<=n;p++)
    {
        for (int i=1;i<=n;i++)
        {
            if (!vis[i])
            {
                if (p==n){
                    ans[p]=i;
                    break;
                }
                int num=n-p;
                if (f[num][x]>=k)
                {
                    vis[i]=1;
                    ans[p]=i;
                    break;
                }
                k-=f[num][x];
                x-=1;
            }
        }
    }
    for (int i=1;i<=n;i++)
    {
        printf("%d",ans[i]);
        if (i!=n) printf(" ");
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值