题目要求构造,但是关于构造很难找到规律,于是在笔者上课列了一堆数据后发现对于一个排列存在一种“环”,一个位置的值指向下一个的地址
现有一个排列[4,3,2,1]其中a1=4,a4=1;a2=3,a3=2;这里存在两个含有2个元素的环,
对于其他排列[4,1,2,3]其中a1=4,a4=3,a3=2,a2=1;这里存在一个含有4个元素的环;
每一个环中重排的代价是环内元素个数-1
而一个排列重排的代价就是所有环的代价之和
通过环的计算不难发现,k至少为n/2(若n为奇数则k至少为n/2-1),至多为n-1
最简单的构造方式就是交换相邻元素,如果是奇数则特殊判断,对最后三个元素交换,就能得到一个重排代价最小的排列
注意到两个环合并之后总代价会增加1,根据这个性质我们只需要合并环,直到代价为k
#include <iostream>
#include <vector>
#define ll long long
using namespace std;
int main() {
ll n,k;cin>>n>>k;
vector<ll>a(n+1);
ll kc=0;
for(int i=2;i<=n;i+=2){
a[i]=i-1;
a[i-1]=i;
kc++;
}
if(a[n]==0){
a[n]=n-2;
a[n-1]=n;
kc++;
}
if(kc>k||k>=n){
cout<<-1<<endl;
return 0;
}
for(int i=3;i<=n&&kc<k;i+=2,kc++){
swap(a[i],a[i-1]);
}
for(int i=1;i<=n;i++){
cout<<a[i]<<" ";
}
cout<<endl;
}

京公网安备 11010502036488号