HDU 6852 Increasing and Decreasing 题解(构造)

题目链接

题目大意

要你构造一个长为n(n<=1e5)的全排列,使得其最长上升子序列和最长下降子序列的长度分别为x和y,而且要使得这个构造的全排列,字典序最小,如果不能构造则输出NO,否则输出YES,并且输出其全排列

题目思路

这个构造比较神奇吧,以前都没有见到过,现在学习一下,其实他的构造方法简单来说就是分段和翻转
如本来是1 2 3 4 5 6 7 8 9 10的全排列 而你如果要构造一个长度为5的单调递减序列那么你就把最后5个元素翻转变成
1 2 3 4 5 10 9 8 7 6 然后假如你要构造4个最长的单调上升子序列,显然是前面5个找三个出来,因为最后这5个数肯定可以有一个元素在最长上升子序列的最后。你就可以把前面5个数分为三段。然后再将这三段分别翻转,而且你的每一段的长度不能超过5,如果超过5了,那么最长下降子序列就会变长,而且你要使得这些分配中,前面段的长度尽可能小(为了保证字典序最小),那么这个排列就会分为
1…2…3 4 5…6 7 8 9 10这四段,然后分别翻转变成1 2 5 4 3 10 9 8 7 6
我不太会证明这个字典序为何是最小的,但是感觉很像(ac就是证明了

然后如何判断是否成立呢,显然最后y个元素翻转后还剩下n-y个元素,要分为x-1段,而且每一段都必须是大于1而且小于等于y即:
1 < = n y x 1 < = y 1<=\frac{n-y}{x-1}<=y
x + y 1 < = n < = x y x+y-1<=n<=x*y
然后自己贪心使得前面的段尽可能短,具体看代码实现

代码

#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<vector>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<unordered_map>
#define fi first
#define se second
#define debug printf(" I am here\n");
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
const ll INF=0x3f3f3f3f3f3f3f3f;
const int maxn=2e5+5,inf=0x3f3f3f3f,mod=998244353;
const double eps=1e-10;
int n,x,y,ans[maxn];
ll pre[maxn],len[maxn];
signed main(){
    int _;scanf("%d",&_);
    while(_--){
        scanf("%d%d%d",&n,&x,&y);
        if(1ll*x*y>=n&&x+y<=n+1){
            printf("YES\n");
            ll res=n-y;
            for(int i=1;i<=x-1;i++){
                len[i]=res-1ll*(x-1-i)*y;
                if(len[i]<=0){
                    len[i]=1;
                }
                res=res-len[i];
                pre[i]=pre[i-1]+len[i];
            }
            for(int i=1;i<=x-1;i++){
                for(int j=pre[i-1]+1;j<=pre[i];j++){
                    ans[i]=pre[i]-j+pre[i-1]+1;
                    printf("%d ",ans[i]);
                }
            }
            for(int i=n;i>=n-y+1;i--){
                printf("%d%c",i,i==n-y+1?'\n':' ');
            }
        }else{
            printf("NO\n");
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_46209312/article/details/107941309
今日推荐