算法第四章上机实践报告
算法第四章上机实践报告
问题描述
算法描述
合并2个长度分别为m和n的数组需要的比较次数为m+n+1,即当m+n最大(最小)时,得到的比较次数最多(最少),每次选取两个最大(最小)的数作为m和n就能得到整体的最多(最少)的合并次数,即得到整体最优解,满足贪心算法的性质
设数组a存储待合并的序列,数组b存储a相同的内容,min和max代表最少和最多的比较次数。a数组按从小到大的顺序排列,每次取前两个数相加,存到第二个数的位置,min的值为这两个数相加再减1,接着对第二个数到最后一个数的子序列从小到大排序,再取子序列的前两位相加存到子序列的第二位,更新min的值,由此类推,直到得到最优解;求max值得过程类似,b数组按从大到小的顺序排列,每次取前两位相加存到第二位的位置,max的值为前两位相加再减1,再从第二位开始的子序列中取前两位相加,更新max值,直到求得最优解,由于最大的两个数相加一定最大,所以b数组仅需一次排序。
问题求解
代码
#include <bits/stdc++.h>
using namespace std;
bool cmp(int a,int b)
{
return a>b;
}
int main()
{
int n,a[20000],b[20000];
cin>>n;
for(int i=0;i<n;i++)
{
cin>>a[i];
b[i]=a[i];
}
int min=0;
for(int i=0;i<n-1;i++)
{
sort(a+i,a+n);
a[i+1]=a[i]+a[i+1];
min+=a[i+1]-1;
}
int max=0;
sort(b,b+n,cmp);
for(int i=0;i<n-1;i++)
{
b[i+1]=b[i]+b[i+1];
max+=b[i+1]-1;
}
cout<<max<<" "<<min;
return 0;
}
时间和空间复杂度
-
时间复杂度:决定时间复杂度的语句为for循环里的sort排序语句,所以最坏情况下的时间复杂度为O(n3),最好情况下的时间复杂度为O(n2logn)
-
空间复杂度:用了辅助数组b存储a数组的内容,所以空间复杂度为O(n)
对贪心算法的理解
贪心算法就是只图眼前利益,不考虑各种可能的整体情况,每一步都选择当前的最优解,以此来实现整体的最优解。但不是所有问题都适合用贪心算法来解决,运用动态规划解决的问题中,很多都要考虑整体的多种可能情况,并不适用贪心算法,贪心算法一般用来解决求最大或最小解