E81086713E446D36F62B2AA2A3502B5EB155

          Java雜家

          雜七雜八。。。一家之言

          BlogJava 首頁 新隨筆 聯系 聚合 管理
            40 Posts :: 1 Stories :: 174 Comments :: 0 Trackbacks
          問題背景
          面對艱巨復雜的技術挑戰,百度所崇尚的系統設計哲學是“簡單可依賴”,而百度的工程師們正在互聯網世界中實踐著這種理念。這里正好有一個挑戰,讓作為百度之星的你小試牛刀:

          在處理數以百億計的網絡信息的過程中,有一個很常見的問題: 
          怎么樣將一個集群上的信息以最低的成本傳輸到另外一個集群上?


          數據源集群A有n臺服務器,編號為 1, 2, ..., n,i號服務器上待傳輸的數據量為Ai ,單位是GB。 
          目的地集群B有m臺服務器,編號為 1, 2, ..., m,j號服務器上的空閑容量為 Bj,單位為 GB。 
          A集群的i號服務器上的每GB數據對于B的集群的j號服務器收益為Vi,j,從 A 集群的 i 號服務器向 B 集群的 j 號服務器傳輸 1GB數據的開銷為Ci,j。 
          你的任務是在保證A中的所有數據傳輸完畢的前提下,性價比V/C盡量高。其中V為所有數據在B集群上的價值之和,C為總開銷。換句話說,若A集群的i號服務器向B集群的j號服務器發送了Ti,j個GB的數據(Ti,j不一定是整數),則性價比定義為:





          輸入格式
          第1行兩個整數n, m(1<=n,m<=50),即集群A和B各自的服務器臺數。
          第2行包含n個不超過100的正整數A1,A2,…,An,即集群A中每臺服務器的待傳輸數據量(單位:GB)。
          第3行包含m個不超過100的正整數B1,B2,…,Bm,即集群B中每臺服務器所能接受的最大數據量(單位:GB)。
          第 4 ~ n+3 行每行包含m個不超過100的非負整數Vi,j,表示集群A的i號服務器中每GB數據對于集群B中的j號服務器的價值。
          第 n+4 ~ 2n+3 行每行包含m個不超過100的正整數Ci,j,表示集群A的i號服務器中每GB數據傳輸到集群B中的j號服務器所需要的開銷。 

          輸出格式
          僅一行,為最大性價比。輸出保留三位小數(四舍五入)。如果A的數據無法傳輸完畢,輸出字符串 “-1”(無引號)。 

          樣例輸入
          2 2
          1 2
          2 1
          11 0
          7 5
          6 1
          3 2 

          樣例輸出
          2.091 

          樣例解釋
          一個方案是:
          集群A的1號服務器把所有數據傳輸到集群B的1號服務器,價值11,開銷6。
          集群A的2號服務器把1GB數據傳輸到集群B的1號服務器,價值7,開銷3,然后把剩下的1GB數據傳輸到集群B的2號服務器,價值5,開銷2。
          性價比:(11+7+5)/(6+3+2)=2.091

          另一個方案是:
          集群A的1號服務器把所有數據傳輸到集群B的2號服務器,價值0,開銷1。
          集群A的2號服務器把所有數據傳輸到集群B的1號服務器,價值14,開銷6。
          性價比:(0+14)/(1+6)=2。

          第一種方案更優

          我的解答:
          該題應該是貪心法可解,每次求性價比最高的,跟部分背包問題很像。
          可惜不是,子問題不是獨立的,我的解法肯定不是最優解。sign~~~,據說是最大流的問題,改天研究研究。
          我的解法用了N+1個最大值堆,一個是全局所有為傳輸完的源站點的最高性價比方案,
          其余每個源站點一個最大值堆含該站點所有傳輸方案。

          //============================================================================
          // Name        : TransportOpt.cpp
          // Author      : Yovn
          // Version     :
          // Copyright   : yovnchine@gmail.com
          //============================================================================

          #include <iostream>
          #include <string>
          #include <cstring>
          #include <cstdio>

          using namespace std;



          int numA;
          int numB;
          int* valuesA;
          int* valuesB;
          int** values=NULL;
          int** costs=NULL;


          typedef struct _HeapNode
          {
              int a;
              int b;
              float vPerC;
             
          }HeapNode;
          class MaxHeap
          {
          public:
              MaxHeap(int n):nodes(new HeapNode[n]),total(n),len(0){
                 
              }
              MaxHeap():nodes(NULL),total(0),len(0){
                     
              }
              ~MaxHeap()
              {
                  delete[] nodes;
              }
              bool isEmpty()
              {
                  return len<=0;
              }
              void setSize(int n)
              {
                  nodes=new HeapNode[n];
                  total=n;
                  len=0;
              }
              HeapNode removeMax()
              {
                 
                  HeapNode ret=nodes[0];
                  nodes[0]=nodes[--len];
                  shift_down(0);
                  return ret;
              }
              void insert(HeapNode val)
              {
                 
                  nodes[len++]=val;
                  shift_up(len-1);
              }
             
          private :
             
             
              void shift_up(int pos) {

                  HeapNode tmp=nodes[pos];
                  int index=(pos-1)/2;
             
                  while (index>=0) {
                      if (tmp.vPerC>nodes[index].vPerC) {
                          nodes[pos]=nodes[index];
                          pos=index;
                          if (pos==0)
                              break;
                          index=(pos-1)/2;
                      } else
                          break;
                  }
                  nodes[pos]=tmp;
              }
              void shift_down(int pos) {

                  HeapNode tmp=nodes[pos];
                  int index=pos*2+1;//use left child
                  while (index<len)//until no child
                  {
                      if (index+1<len&&nodes[index+1].vPerC>nodes[index].vPerC)//right child is smaller
                      {
                          index+=1;//switch to right child
                      }
                      if (tmp.vPerC<nodes[index].vPerC) {
                          nodes[pos]=nodes[index];
                          pos=index;
                          index=pos*2+1;

                      } else {
                          break;
                      }

                  }
                  nodes[pos]=tmp;
                 
              }
              HeapNode* nodes;
              int total;
              int len;


             
          };

          void parseToInts(string& line, int* arr, int num) {
              int pos=0;
              for (int i=0; i<line.length(); i++) {
                  if (line[i]>='0'&&line[i]<='9') {
                      if (line[i+1]>='0'&&line[i+1]<='9') {
                          int a=(line[i]-'0')*10+(line[i+1]-'0');
                          arr[pos++]=a;
                          i++;
                      } else {
                          int a=(line[i]-'0');
                          arr[pos++]=a;
                         
                      }
                     
                  }
              }
          }
          void input()
          {
              string line;
              getline(cin,line);
             
              sscanf(line.c_str(),"%d %d",&numA,&numB);
              valuesA=new int[numA];
              valuesB=new int[numB];
              line.clear();
              getline(cin,line);
              parseToInts(line,valuesA,numA);
             
              line.clear();
              getline(cin,line);
              parseToInts(line,valuesB,numB);
             
            
              values=new int*[numA];
              costs=new int*[numA];
              for (int i=0; i<numA; i++) {
                  values[i]=new int[numB];
                  line.clear();
                  getline(cin, line);
                  parseToInts(line, values[i], numB);
              }
             
              for (int i=0; i<numA; i++) {
                  costs[i]=new int[numB];
                  line.clear();
                  getline(cin, line);
                  parseToInts(line, costs[i], numB);
              }
             
             
             
          }
          bool validate() {
              int sumA=0, sumB=0;
              for (int i=0; i<numA; i++) {
                  sumA+=valuesA[i];
              }
              for (int i=0; i<numB; i++) {
                  sumB+=valuesB[i];
              }
              return sumA<=sumB;
          }
          void calc() {
              MaxHeap totalHeap(numA);
              MaxHeap* aHeaps=new MaxHeap[numA];
              int totalC=0;
              int totalV=0;

              if(!validate())
              {
                  printf("-1\n");
                  return;
              }
              for (int i=0; i<numA; i++) {

                  aHeaps[i].setSize(numB);
                  for(int j=0;j<numB;j++)
                  {
                      HeapNode node;
                      node.a=i;
                      node.b=j;
                      node.vPerC=(float)values[i][j]/(float)costs[i][j];
                      aHeaps[i].insert(node);
                  }
                  totalHeap.insert(aHeaps[i].removeMax());
              }
              while(!totalHeap.isEmpty())
              {
                  HeapNode node=totalHeap.removeMax();
             
                  if(valuesA[node.a]==valuesB[node.b])
                  {
                      totalV+=values[node.a][node.b]*valuesA[node.a];
                      totalC+=costs[node.a][node.b]*valuesA[node.a];
                      valuesB[node.b]=0;
                      valuesA[node.a]=0;
                     
                  }
                  else if(valuesA[node.a]>valuesB[node.b])
                  {
                      totalV+=values[node.a][node.b]*valuesB[node.b];
                      totalC+=costs[node.a][node.b]*valuesB[node.b];
                      valuesA[node.a]-=valuesB[node.b];
                      valuesB[node.b]=0;
                     
                  }
                  else
                  {
                      totalV+=values[node.a][node.b]*valuesA[node.a];
                      totalC+=costs[node.a][node.b]*valuesA[node.a];
                      valuesB[node.b]-=valuesA[node.a];
                     
                      valuesA[node.a]=0;
                 
                  }
                  while(!aHeaps[node.a].isEmpty())
                  {
                      HeapNode todo=aHeaps[node.a].removeMax();
                      if(valuesA[todo.a]>0&&valuesB[todo.b]>0)
                      {
                          totalHeap.insert(todo);
                          break;
                      }
                  }
              }
              printf("%lf\n",(float)totalV/totalC);
          }
          int main() {
             
              input();
              calc();
             
              return 0;
          }




          posted on 2008-06-01 18:53 DoubleH 閱讀(2444) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 武冈市| 揭西县| 昌江| 宝应县| 石景山区| 互助| 德昌县| 响水县| 金寨县| 都江堰市| 安康市| 高唐县| 横山县| 洱源县| 临沧市| 泸州市| 龙州县| 马尔康县| 兴国县| 漠河县| 乌苏市| 临高县| 宝山区| 工布江达县| 铜山县| 伊金霍洛旗| 星座| 来宾市| 丰原市| 桂林市| 汉沽区| 佛冈县| 阿拉善盟| 蒙自县| 宽城| 庆安县| 三明市| 济南市| 黄梅县| 博罗县| 沙坪坝区|