4-13 数列极差问题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
算法实现题4-13
★问题描述:在黑板上写了N个整数组成的一个数列,进行如下操作:每一次擦去其中2个数,设为a和b,然后在数列中加入一个数a∙b+1,如此下去直至黑板上只剩下一个数。在所有按这种操作方式最后得到的数中,最大的数记为max,最小的数记为min,则该数列的极差M定义为M=max-min。
★编程任务:对于给定的数列,编程计算出其极差M。
★算法分析:
在数列极差问题中,问题的难点是求出max,min的值。因为在N个正整数组成的数列中,用穷举法的话每次要擦去2个数的选择有很多,所以不可能每种选择的结果都计算出来,这样的话计算量非常大。所以我们主要解决的问题是找出一个方法求出max,min的值。
贪心算法最重要的两个性质是:贪心选择性质和最优子结构性质。贪心选择性质是所求问题的整体最优解可以通过一系列局部最优的选择,也就是贪心选择来达到。而最优子结构性质是指一个问题的最优解包含其子问题的最优解。
问题的关键就是max,min值的求解问题,所以首先看下怎么样来求max,min 值。设有三个数x y z,且x
我们在看下用贪心策略求解的合理性:假设经(N-3)次运算后得到3个数:x y max(max>x>y),其中max是(N-2)个数经(N-3)次运算后所得的最大值,此时最大值m =(x*y+1)×max+1。若经(N-2)次变换后所得的3个数为:x y z(z>x>y)且z不为(N-2)次变换后的最大值,即z<max 则所求得的最大值为:m’=(x*y+1)*z+1,此时m-m’ =(1+x*y)(max -z)>0 所以此时不为最优解。所以若使第k(1≤k≤N-1)次变换后所得值最大,必使(k-1)次变换后所得值最大(符合贪心策略的最优子结构性质),在进行第k次变换时,只需取在进行(k-1)次变换后所得数列中的两最小数x,y进行运算,再把结果插入到数列即可。(符合贪心策略的贪心选择性质)。
★算法设计:
先将数列a[]按从小到大顺序排列,由得出结论(优先选择数列中最小的2个数进行(a*b+1)运算得到的值大,优先选择数列中最大的2个数进行(a*b+1)运算得到的值小)来计算max和min,最后求极差(max-min)。
★程序代码:
#include
#define M 2001
//将数列元素按从大到小顺序进行快速排序
void QuickSort(int a[],int low,int high)
{
int pivot=a[low],i=low,j=high;
while(i { while(i j--; if(i a[i++]=a[j]; while(i i++; if(i a[j--]=a[i]; } a[i]=pivot; if(low QuickSort(a,low,i-1); if(i QuickSort(a,i+1,high); } void main() { int n,a[M],max,min; printf("输入数列长度:\n"); scanf("%d",&n); printf("输入数列:\n"); while(n) { for(int i=0;i scanf("%d",&a[i]); QuickSort(a,0,n-1); //求最大值 max=a[0]; for(i=1;i max=max*a[i]+1; //求最小值 min=a[n-1]; for(i=n-2;i>=0;i--) min=min*a[i]+1; printf("极差为:\n"); printf("%d\n",max-min); } getchar(); } ★运行结果: