这是什么算法?分发有限资源的最佳方式

时间:2015-03-24 01:30:25

标签: algorithm computer-science

我最近在编程挑战中看到了这个问题,我想知道哪个着名的CS算法很像。我实施了原油解决方案。我知道必须有更好的方法来做,但我不确定要搜索的术语。 似乎就像背包问题的一个变种......但是有足够的差异让我感到有点难过。

问题:

有3个城市(A,B,C)有人口(100,100,200)。你可以建4所医院。建立医院,以便最大限度地减少访问每个医院的人数。

在这个例子中,答案是:A中的1,B中的1和C中的2。这意味着每个医院服务100人(最佳解决方案)。

例如,如果您将医院分配为A中的1,B中的2和C中的1,您将平均(100,50,200),这会给您最差的200(不是最佳)溶液)。

感谢。

附录:

  • 为了简化问题,医院数量将始终为>=个城市数量。每个城市至少应该有一家医院。

3 个答案:

答案 0 :(得分:4)

  1. 为每个城市分配医院
  2. 医院离开时
  3. 计算每个城市的人口与医院比率
  4. 将医院分配给比率最高的医院
  5. 循环

答案 1 :(得分:2)

使用二进制搜索可以解决此问题。因此,我们搜索医院服务的最少人数。

伪代码:

int start = 0;
int end =//total population
while(start <= end)
    int mid = (start + end)/2;
    for(each city)
       Calculate the number of hospital needed to achieve mid = (population/mid)
    if(total of number of hospital needed <= number of available hospital)
       decrease end;
    else
       increase start;   

时间复杂度 O(n log m),n是城市数,m是总人口。

答案 2 :(得分:2)

这是可以使用动态编程解决的问题的示例。以下工作java code在O(M * N ^ 2)时间内解决了这个问题,其中
M =城市数量,并且
N =医院总数

public void run(){
        arr[0] = 100;
        arr[1] = 100;
        arr[2] = 200;
        System.out.println(minCost(0, 4));
        printBestAllocation(0, 4, minCost(0, 4));
    }

    static HashMap<String, Integer> map = new HashMap<String, Integer>();

    // prints the allocation of hospitals from the ith city onwards when there are n hospitals and the answer for this subproblem is 'ans'
    static void printBestAllocation(int i, int n, int ans){
        if(i>=arr.length){
            return;
        }
        if(n<=0){
            throw new RuntimeException();
        }

        int remainingCities = arr.length - i - 1;
        for(int place=1; place<=n-remainingCities; place++){
            if(arr[i] % place == 0){
                int ppl = Math.max(arr[i] / place, minCost(i+1, n-place));
                if(ppl == ans){

                    System.out.print(place + " ");
                    printBestAllocation(i+1, n-place, minCost(i+1, n-place));
                    return;
                }
            }else{
                int ppl = Math.max(arr[i] / place + 1, minCost(i+1, n-place));
                if(ppl==ans){
                    System.out.print(place + " ");
                    printBestAllocation(i+1, n-place, minCost(i+1, n-place));
                    return;
                }
            }
        }
        throw new RuntimeException("Buggy code. If this exception is raised");
    }

    // Returns the maximum number of people that will be visiting a hospital for the best allocation of n hospitals from the ith city onwards.
    static int minCost(int i, int n){
        if(i>=arr.length){
            return 0;
        }
        if(n<=0){
            throw new RuntimeException();
        }
        String s = i + " " + n;
        if(map.containsKey(s)){
            return map.get(s);
        }
        int remainingCities = arr.length - i - 1;
        int best = Integer.MAX_VALUE;
        for(int place=1; place<=n-remainingCities; place++){
            int ppl;
            if(arr[i] % place==0){
                ppl = Math.max(arr[i] / place, minCost(i+1, n-place));
            }else{
                ppl = Math.max(arr[i] / place + 1, minCost(i+1, n-place));
            }
            best = Math.min(best, ppl);
        }
        map.put(s, best);
        return best;
    }

状态将是(i,n),其中i代表第i个城市,n代表可用的医院数量。它代表了从第i个城市到最后从n医院获得最佳分配的最高人数。所以答案是针对你问题中的例子的状态(0,4)。

现在,在每个城市,您最多可以放置

maxHospitals = n-remainingCities 医院,其中
remainingCities = totalCities-i-1

因此,首先将该城市至少一家医院放到maxHospitals,然后重复出现其他较小的子问题。

状态数= O(M * N ^ 2)
每州的时间= O(1)

因此,时间复杂度= O(M * N ^ 2)