题目链接:http://acm.hit.edu.cn/hoj/problem/view?id=1062
本题练习贪心。
对于这个问题 先通过实例来认识问题所描述的计算过程。
令N=3取数列3,5,7
可能有下面三种情况
(3×5+1)×7+1=113
(3×7+1)×5+1=111
(5×7+1)×3+1=109。
由此可见先运算小数据的到的是最大值先运算大数据得到的是最小值。
故针对此问题可采用贪婪算法 下面验证其合理性
不妨假设3个数a<b<c则它们可以表示为 b=a+k1 ,c=a+k1+k2
则有以下几种组合计算结果
1(a×b+1)×c+1=a×a×a+(2k1+k2)a×a+(k1(k1+k2)+1)×a+k1+k2+1
2(a×c+1)×b+1=a×a×a+(2k1+k2)a×a+(k1(k1+k2)+1)×a+k1+1
3(b×c+1)×a+1=a×a×a+(2k1+k2)a×a+(k1(k1+k2)+1)×a+1
显然可使用贪婪策略。在求最大值的时候要选择较小的数操作反过来求最小值时要选择较大的数操作。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
using namespace std;
int array1[5002];
int array2[5002];
bool cmp(int a,int b)
{
return a>b;
}
bool cmp2(int a,int b)
{
return a<b;
}
int max(int n)
{
while(n>2)
{
sort(array1,array1+n,cmp);
array1[n-2] = array1[n-2] * array1[n-1] + 1;
n--;
}
return array1[0] * array1[1] + 1;
}
int min(int n)
{
while(n>2)
{
sort(array2,array2+n,cmp2);
array2[n-2] = array2[n-2] * array2[n-1] + 1;
n--;
}
return array2[0] * array2[1] + 1;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
int n;
while(scanf("%d",&n)!=EOF && n!=0)
{
for(int i=0; i<n; i++)
{
scanf("%d",&array1[i]);
array2[i] = array1[i];
}
printf("%d\n",max(n) - min(n));
}
return 0;
}