数列 {An} 为N的一种排列。
例如N=3,可能的排列共6种:
1
2
3
4
5
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)的最小值和最大值分别是多少。
输入描述:
第一行输入1个整数T,表示测试用例的组数。( 1 <= T <= 10 )
第二行开始,共T行,每行包含1个整数N,表示数列 {An} 的元素个数。
( 1 <= N <= 100,000 )
输出描述:
共T行,每行2个整数,分别表示F(N)最小值和最大值
示例1
输入
2
2
3
2
3
输出
1 1
0 2
0 2
说明
对于N=3:
- 当{An}为3,2,1时可以得到F(N)的最小值0
- 当{An}为2,1,3时可以得到F(N)的最大值2
- 当{An}为3,2,1时可以得到F(N)的最小值0
- 当{An}为2,1,3时可以得到F(N)的最大值2
备注:
对于60%的数据有: 1 <= N <= 100对于100%的数据有:1 <= N <= 100,000
解题过程
刚开始我只是考虑用类似全排列算法的方法 并且编写了代码 但最后发现当N够大 这个复杂度是完全不符合的后来就想到了找规律
首先F(X)肯定>=0 那么最小值肯定>=0
如果每四个为一组 如5 6 7 8 那么最小值不就是8-6-(7-5)=0
这样的话我们可以取使得x的最后四位一定为0 Fx的最小值=F(x%4)的最小值 即如果x为5 那么1 2 3 4 5 由于2 3 4 5最小值为0则F5最小值=F1
所以我们只要求F1 F2 F3的最小值即可
示例的X=1 2 3时 F(x)min分别为 1 1 0
然后 F(x)=|F(x-1)-A[x]| 要想fx最大,F(x-1)肯定要最小或者最大
F(x) max不就是在 |A(x)-F(x-1)min |和 |A(x)-F(x-1)max |取大值吗
#include<iostream>
#include<cstdlib>
using namespace std;
int Max_Min[100000][2] ; //A[x][0] F(x)最大值 A[x][1]最小值
void func(int x) {
for (int i = 2; i <= x; i++) {
int m = abs(Max_Min[i - 1][0] - i);
int n = abs(Max_Min[i - 1][1] - i);
Max_Min[i][0] = m > n ? m : n;
Max_Min[i][1] = Max_Min[i%4][1];
}
cout << Max_Min[x][1] << " " << Max_Min[x][0] << endl;
}
int main() {
//最大值赋值
Max_Min[1][0] = 1;
//最小值赋值
Max_Min[1][1] = 1;
Max_Min[2][1] = 1;
Max_Min[3][1] = 0;
int T; //测试组
cin >> T;
int* N = new int[T + 1];
for (int i = 1; i <= T; i++)
cin >> N[i];
for (int i=1;i<=T;i++)
{
func(N[i]);
}
delete[]N;
}