hdu 4655 (组合数)

点击打开链接


题意:

给你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;
}

	
	


你可能感兴趣的:(HDU,组合数,多校联赛6)