贪心算法通常是对某一值进行排序,然后再采取贪心策略进行求解。此问题贪心角度不同以往。它的排序不是严格单调排列,而是将相应值的分布从中间往两边依次减少排列。
题意:设磁盘上有n个文件,f1,f2,…,fn,,每个文件占磁盘上1个磁道。这n个文件的检索概率分别是p1,p2,…,pn,且p1+p2+…+pn =1。磁头从当前磁道移到被检信息磁道所需的时间可用这2个磁道之间的径向距离来度量。如果文件pi存放在第i道上,1<i<n ,则检索这n 个文件的期望时间是 ∑【Pi*Pj*d(i,j)】 ,其中 d(i,j)是第i道与第j 道之间的径向距离|i-j|。
代码:
/** @贪心算法-磁盘文件最优存储问题 @ author-狂热的coder */ #include<iostream> #include<algorithm> using namespace std; bool cmp(int a,int b){ return a>b; } /*将数组a的值排序使其元素的分布从中间往两边依次减少*/ void strageSort(int n,int a[]){ int i,k,mid; sort(a,a+n,cmp); mid = n/2; int b[n+1]; b[mid] = a[0]; for(i = 1,k = 1;i< n;i++,k++){ //数组a的值分布从中间往两边依次减少 b[mid-k] = a[i]; i++; if(i!=n) b[mid+k] = a[i]; } for(int i = 0;i<n;i++){ //经变化后的a数组 a[i] = b[i]; } } void minStorage(int n,int a[]){ int sum = 0; for(int i = 0;i<n;i++){ sum+=a[i]; } double result = 0; for(int i = 0;i<n;i++){ for(int j = i+1;j<n;j++){ //从磁道0-n-1。计算它们的磁道间的检索时间 result+=(a[i]*1.0/sum)*(a[j]*1.0/sum)*(j-i); } } cout<<"最小期望检索时间:"<<result<<endl; } int main(){ int n,k,mid,i; cout<<"输入文件个数"<<endl; cin>>n; int a[n+1]; cout<<"输入文件的检索概率:"<<endl; for(int i = 0;i<n;i++){ cin>>a[i]; } strageSort(n,a); minStorage(n,a); return 0; } /* 5 9 11 22 33 55 */