HDUOJ 6852 Increasing and Decreasing
Problem Description
Notice:Don’t output extra spaces at the end of one line.
Given n,x,y, please construct a permutation of length n, satisfying that:
- The length of LIS(Longest Increasing Subsequence) is equal to x.
- The length of LDS(Longest Decreasing Subsequence) is equal to y.
If there are multiple possible permutations satisfying all the conditions, print the lexicographically minimum one.
Input
The first line contains an integer T(1≤T≤100), indicating the number of test cases.
Each test case contains one line, which contains three integers n,x,y(1≤n≤1e5,1≤x,y≤n).
Output
For each test case, the first line contains "YES’’ or "NO’’, indicating if the answer exists. If the answer exists, output another line which contains n integers, indicating the permutation.
Sample Input
4
10 1 10
10 10 1
10 5 5
10 8 8
Sample Output
YES
10 9 8 7 6 5 4 3 2 1
YES
1 2 3 4 5 6 7 8 9 10
YES
1 2 3 5 4 10 9 8 7 6
NO
思维+构造~
很容易发现,LIS的长度就是LDS的个数,LDS的长度就是LIS的个数~
那么输出 -1 时就是 n ≥ x ∗ y + 1 n\geq x*y+1 n≥x∗y+1 和 n < x + y − 1 n<x+y-1 n<x+y−1
下面考虑构造,我们根据上面发现的规律就可以把 n n n 分成 x x x 组,但题目要求字典序最小,也即分块时要让后面的块尽可能最大,答案用栈存储即可,AC代码如下:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int t;
ll n,a,b;
int main(){
scanf("%d",&t);
while(t--){
scanf("%lld%lld%lld",&n,&a,&b);
if(n>=a*b+1||n<a+b-1) printf("NO\n");
else{
printf("YES\n");
stack<int>ans;
while(a){
if(n-b>=a-1){
for(int i=n-b+1;i<=n;i++) ans.push(i);
n-=b;
a--;
}else b=n+1-a;
}
while(!ans.empty()){
printf("%d",ans.top());
ans.pop();
if(!ans.empty()) printf(" ");
else printf("\n");
}
}
}
return 0;
}