[编程题]多多的排列函数

数列 {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:
F(x) = \left{ \begin{aligned} & A_1 & (x = 1) \ & | F(x - 1) - A_x | & (x > 1) \ \end{aligned} \right.F(x)={​
其中|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

输出

1 1
0 2

说明

对于N=3:
- 当{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;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

张_0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值