hdu 4655 (组合数)

本文介绍了一种通过特定排序方式来求解给定数组排列问题的方法,旨在找到一种排列方式使得所有情况的piece总数最大。该方法首先将数组逆序排序,再采用特殊模式重新排列,最终计算出最大piece总数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

点击打开链接


题意:

给你n个数,求如何排这n个数,使S最大,S是所有情况的piece总数。。。


主要在于求排序的情况

应该为            ...a(n-1),a1,an,a2,a(n-2)...          an为最大数。。。。

每次进行相邻两个的比较,取小的,则这两个位置出现同中情况的个数就为最小的这个数,然后求这两个数的前后各有多少中情况,相乘就是这两个相邻的数相同的情况,用总数(所有数的乘积*n,n个位置全部不同)减去所有相同的就是不同的。。。。


#include"stdio.h"
#include"string.h"
#include"algorithm"
using namespace std;
#define N 1000006
#define M 1000000007
typedef __int64 LL;

LL cmp(LL a,LL b)
{
	return a>b;
}
LL min(LL a,LL b)
{
	return a<b?a:b;
}

LL A[N];
LL t[2*N];
LL B[N];
LL C[N];
int main()
{
	LL T;
	LL n;
	LL i,j;
	scanf("%I64d",&T);
	while(T--)
	{
		scanf("%I64d",&n);
		for(i=1;i<=n;i++)
			scanf("%I64d",&A[i]);
		sort(A+1,A+n+1,cmp);

		int x,y;
		int a,b;
		int f;
		f=1;
		a=999999;
		t[a+1]=A[1];
		b=a+2;
		x=2;y=n;
		while(x<=y)
		{
			if(f==1)
			{
				t[a--]=A[y--];
				if(x>y)break;
				t[b++]=A[y--];
				if(x>y)break;
				f=0;
			}
			else
			{
				t[a--]=A[x++];
				if(x>y)break;
				t[b++]=A[x++];
				if(x>y)break;
				f=1;
			}
		}
		j=1;
		for(i=a+1;i<=b-1;i++)
		{
			A[j++]=t[i];
		//	printf("%d ",t[i]);
		}	
		B[0]=1;
		B[1]=A[1];
		for(i=2;i<=n;i++)
			B[i]=(B[i-1]*A[i])%M;
		C[n+1]=1;
		C[n]=A[n];
		for(i=n-1;i>=1;i--)
			C[i]=(C[i+1]*A[i])%M;
		LL ans=(B[n]*n)%M;
		for(i=2;i<=n;i++)
		{
			ans-=((min(A[i],A[i-1])*C[i+1])%M*B[i-2])%M;
			if(ans<0)ans+=M;
			ans%=M;
		}
		printf("%I64d\n",ans%M);
	}
	return 0;
}

	
	


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值