多多的排列函数
数列 {An} 为N的一种排列。
例如N=3,可能的排列共6种:
1, 2, 3
1, 3, 2
2, 1, 3
2, 3, 1
3, 1, 2
3, 2, 1
定义函数F:
其中|X|表示X的绝对值。
现在多多鸡想知道,在所有可能的数列 {An} 中,F(N)的最小值和最大值分别是多少。
n的范围有1e5排列组合的数量肯定特别大,结合它给出的递推公式我们能猜到:这些最大值最小值之间是有规律的。
列举前几项算出最大值和最小值:
- 2:min:1 max:1
- 3:min:0 max:2
- 4:min:0 max:4
- 5:min:1 max:5
欲求当前的最大值,只要让它前面的i-1个排序保证最小,再减去新加入的最大值:
i-1 i-2 … 1 i
求最小值时将前一个的最大值末尾与i交换
i-2 i-3 … 1 i i-1
经过分析退出结论:
F[i]max = i-F[i-1]min
F[i]min = abs(F[i-1]max-i+2)
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
int main()
{
int t;
cin>>t;
int fmin[100005];
int fmax[100005];
fmin[1]=1;
fmax[1]=1;
fmin[2]=1;
fmax[2]=1;
for(int i=3;i<=100000;i++)
{
fmax[i]=i-fmin[i-1];
fmin[i]=abs(fmax[i-1]+1-(i-1));
}
while(t--)
{
int n;
cin>>n;
cout<<fmin[n]<<' '<<fmax[n]<<endl;
}
return 0;
}