最大化
题意:
给你n个整数,a[1]....a[n],请重新排列这些整数,使得式子的值最大。请输出S的最大值。
第一行一个整数n(2 <= n <= 100000),表示数字的个数;
第二行为n个整数 (1 <= ai <= 1000000000)
思路:
给个例子: n=5 ,设排列后(假设是答案)的5个整数分别为 a b c d e , 显然按照上面计算S的公式, 数字 a e 只用到一次,而 b c d 用到两次,再考虑(-1)^i ,所以前面的系数应该分别为 -1,2,-2,2,-1 ,然后排序可得 -2,-1,-1,2,2 ,对那n个数也从小到大排序得到 a e d c b, 然后系数小的乘以整数小的,系数大的乘以整数大的就得出结果。 (例如 S = (-2)*a + (-1)*e + (-1)*d + 2*c + 2* b ) 。 注意,如果是n是偶数的话,系数的最后一项就变成 1 。
好像按以前的经验也直接可得,如果1 2 3 4 5 ,答案的排列应该是 4 1 5 2 3 , 就是尽量使大的数和小的数 放在中间(因为能用2遍)。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 const int N = 1e5 + 10; 2 int a[N], c[N]; 3 int main() { 4 int n; 5 //freopen("data3.in", "r", stdin); 6 //freopen("data3.out", "w", stdout); 7 scanf("%d", &n); 8 for (int i = 1; i <= n; i++) scanf("%d", &a[i]); 9 c[1]=-1; 10 for (int i = 2; i <= n-1; i++) { 11 if(i&1) c[i]=-2; 12 else c[i]=2; 13 } 14 if(n%2) c[n]=-1; 15 else c[n]=1; 16 17 sort(c+1, c+n+1); 18 sort(a+1, a+n+1); 19 LL ans = 0; 20 for (int i = 1; i <= n; i++) ans += 1LL * c[i] * a[i]; 21 printf("%lld\n", ans); 22 return 0; 23 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 int n,a[N]; 2 3 int main() 4 { 5 cin>>n; 6 for(int i=1;i<=n;i++){ 7 scanf("%d",&a[i]); 8 } 9 sort(a+1,a+1+n); 10 ll ans=0; 11 if(n%2) 12 { 13 for(int i=1;i<=n/2;i++) 14 ans-= 1LL*a[i]*2; 15 for(int i=n/2+3;i<=n;i++) 16 ans+= 1LL*a[i]*2; 17 ans+= 1LL*(a[n/2+1]+a[n/2+2]); 18 } 19 else 20 { 21 for(int i=1;i<=n/2;i++) 22 ans-= 1LL*a[i]*2; 23 for(int i=n/2+2;i<=n;i++) 24 ans+= 1ll*a[i]*2; 25 ans+= 1LL*(a[n/2]+a[n/2+1]); 26 } 27 cout<<ans<<endl; 28 }