设磁盘上有n个文件f1,f2,…,fn,每个文件占用磁盘上的1个磁道。这n个文件的检索概率分别是p1,p2,…,pn,且 =1。磁头从当前磁道移到被检信息磁道所需的时间可用这2个磁道之间的径向距离来度量。如果文件fi存放在第i道上,1≦i≦n,则检索这n个文件的期望时间是对于所有的i<j,time+=pi*pj*d(i,j) 。其中d(i,j)是第i道与第j道之间的径向距离|i-j|。
磁盘文件的最优存储问题要求确定这n个文件在磁盘上的存储位置,使期望检索时间达到最小。
要求:
输入:第1行是正整数n,表示文件个数。第2行有n个正整数ai,表示文件的检索概率。
输出:计算出的最小期望检索时间。
思路:
先将n个文件按访问概率从大到小排序,概率最大的应该放中间,次大的和次次大的放最大的两边,再小一点的再放在次大的左边和次次大的右边
具体算法:
将文件按概率排序后,用一个新的数组代表各文件存放位置,先确定mid值,再依次确定mid两边,mid两边的两边的各文件,不断的循环,最后各文件就再新的数组里放好了位置
C++代码
- #include <stdio.h>
- #include <algorithm>
- int cmp (const void *a , const void *b) {
- return *(double *)a – *(double *)b;
- }
- double greedy(double a[],int n) {
- qsort(a,n,sizeof(double),cmp);
- int mid = (n – 1) / 2;
- double x[n];
- x[mid] = a[n-1];
- for(int i = mid+1;i < n;i++)
- x[i] = a[n – 2*(i-mid)];
- for(int i = mid-1;i >= 0;i–)
- x[i] = a[n – 2*(mid-i) – 1];
- double sum = 0,exp = 0;
- for(int i = 0;i < n;i++) {
- sum += a[i];
- for(int j = i+1;j < n;j++)
- exp += x[i]*x[j]*(j-i);
- }
- return exp/sum/sum;
- }
- int main() {
- int i,j,n;
- double a[1000],exp;
- scanf(“%d”,&n);
- for(i = 0;i < n;i++)
- scanf(“%lf”,&a[i]);
- exp = greedy(a,n);
- printf(“%lf/n”,exp);
- }