CF1728B Best Permutation

考虑对权值产生贡献的数在哪里。

显然对于一个排列 pp,我们设 ii 为最大的下标位置,且进行到 ii 时 x=0x = 0。那么对答案有影响的是 pi+1p_{i+1} 到 pnp_n。

第一个结论,pi+1p_{i+1} 至 pnp_n 严格单调递增。若存在 pj≤pj−1(i<j≤n)p_j \leq p_{j-1}(i < j \leq n),那么进行到 jj 时,xx 一定会重新赋值为 00。

第二个结论,排列最终权值 x≤2⋅pn−1x \leq 2 \cdot p_n - 1,进行到 nn 时,如果 x<pnx < p_n,那么 x←x+pnx \leftarrow x + p_n,不然 x←0x \leftarrow 0。显然最终的 x+pn<pn+pn=2⋅pnx+p_n < p_n + p_n = 2 \cdot p_n。

至此很好想,只需要令 i=n−2,pn−1=n−1,pn=ni=n-2, p_{n-1} = n-1, p_n = n 即可,答案是最大的。

然而我们还需要构造 11 至 ii:

若 n≡0(mod2)n \equiv 0 \pmod 2,令 p=[n−2,n−3,n−4,⋯ ,n−I−1,⋯ ,2,1,n−1,n]p = [n-2, n - 3,n-4, \cdots, n-I-1, \cdots, 2, 1, n-1,n]。这里的 II 表示下标,且 1≤I≤n−21 \leq I \leq n - 2。可以发现 n−2n-2 和 n−3n-3,n−4n-4 和 n−5n-5,⋯\cdots,两两抵消。

若 n≡1(mod2)n \equiv 1 \pmod 2,考虑在 pp 的前面构造 1,2,31, 2, 3,这时剩下的就是偶数,按照上述情况做即可。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;

const int N = 105;

int n, a[N], t;

int main()
{
	scanf("%d", &t);
	while (t--)
	{
		scanf("%d", &n);
		if (!(n & 1))
		{
			int cur = 1;
			while (cur < n - 1)
			{
				a[cur] = n - (cur + 1);
				cur++;
			}
			a[n - 1] = n - 1;
			a[n] = n;
			for (int i = 1; i <= n; i++) printf("%d ", a[i]);
			printf("\n");
		}
		else
		{
			if (n == 5) printf("1 2 3 4 5\n");
			else
			{
				a[1] = 1, a[2] = 2, a[3] = 3;
				int cur = 4;
				while (cur < n - 1)
				{
					a[cur] = n - (cur - 2);
					cur++;
				}
				a[n - 1] = n - 1;
				a[n] = n;
				for (int i = 1; i <= n; i++) printf("%d ", a[i]);
				printf("\n");
			}
		}
	}
	return 0;
}
posted @ 2022-09-10 12:24  HappyBobb  阅读(35)  评论(0)    收藏  举报  来源