题目链接 http://acm.uestc.edu.cn/problem.php?pid=1644
题目大意:给定一个序列【长度小于50】,你可以随意调整序列的顺序,然后进行如下变换
a[i]=a[i]-a[i+1]
之后序列剩下最后一个数,求最后这个数的最大值。
TAG:数学 排序
水题一枚。。
可以发现,一个含有n个数的序列,按照一个顺序排列时,最后剩下的一个数是:
C(n-1,0)*a[0]-C(n-1,1)*a[1]+C(n-1,2)*a[2]-……C(n-1,n-1)*a[n-1]
所以我们可以先算出C(n-1,i),然后把其中的偶数位都换成负的,然后排序。
之后把a数组也排序,之后对应相乘求和。
最后的结果就是所求最大值
代码如下:
/*******************************************************************************************
* user_id = 135678942570 run_id = 290259
******************************************************************************************/
#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
main()
{
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
int t,cas=0;
long long int c[51][51]={0};
c[0][0]=1;
c[1][0]=1;
c[1][1]=1;
for(int i=2;i<=50;i++)
{
c[i][0]=1;
c[i][i]=1;
for(int j=1;j<i;j++)
c[i][j]=c[i-1][j]+c[i-1][j-1];
}
for(int i=1;i<=50;i++)
{
for(int j=1;j<=i;j++)
if(j%2)
c[i][j]=-c[i][j];
sort(c[i],c[i]+i+1);
}
for(scanf("%d",&t);t;t--)
{
printf("Case #%d: ",++cas);
int n;
int num[55]={0};
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&num[i]);
sort(num,num+n);
long long res=0;
for(int i=0;i<n;i++)
res+=c[n-1][i]*num[i];
printf("%lld\n",res);
}
return 0;
}