算法设计与分析: 3-24 有向直线2中值问题

该博客介绍了如何解决有向直线2中值问题,即在一条有向直线上寻找最佳的两个增设服务机构位置,以最小化服务转移费用。问题涉及到权值分配、运输费用和动态规划策略。文章提供了数据输入格式和Java编程实现,并引用了王晓东《计算机算法设计与分析》的相关内容作为参考。

3-24 有向直线2中值问题


问题描述

给定一条有向直线L以及L上的n+1个点x0<x1<...<xnx0<x1<...<xn。有向直线L上的每个点xixi都有一个权w(xi)w(xi);每条有向边(xi,xi1)(xi,xi−1)也都有一个非负边长d(xi,xi1)d(xi,xi−1)。有向直线L上的 每个点xixi 可以看作客户,其服务需求量为w(xi)w(xi)。每条边(xi,xi1)(xi,xi−1)的边长d(xi,xi1)d(xi,xi−1)可以看作运输费用。如果在点xixi 处未设置服务机构,则将点xixi 处的服务需求沿有向边转移到点xjxj 处服务机构需付出的服务转移费用为w(xi)d(xi,xj)w(xi)∗d(xi,xj)。在点x0x0 处已设置了服务机构,现在要在直线 L 上增设 2 处服务机构,使得整体服务转移费用最小。

对于给定的有向直线 L,编程计算在直线 L 上增设 2 处服务机构的最小服务转移费用。

数据输入:
第 1 行有 1 个正整数 n,表示有向直线 L 上除了点 x0x0
还有n个点x0<x1<...<xnx0<x1<...<xn。接下来的n行中,每行有2个整数。第i+1行的2个整数分别表示 w(xni1)w(xn−i−1)d(xni1,xni2)d(xn−i−1,xn−i−2)


Java

import java.util.Scanner;

public class YouXiangZhiXian2ZhongZhi {
    private static int n;
    private static int[] dist,wt;
    private static int tot,mincost;
    private static int MAXCOST = 99999999;

    public static void main(String[] args){
        Scanner input = new Scanner(System.in);
        int d,w;

        while (true){
            n = input.nextInt();
            dist = new int[n+2];
            wt = new int[n+1];


            dist[1] = 0;
            wt[1] = input.nextInt();
            dist[2] = input.nextInt();

            tot = wt[1] * dist[2];

            for(int i=2; i<=n; i++){
                w = input.nextInt();
                d = input.nextInt();
                wt[i] = wt[i-1] + w;
                dist[i+1] = dist[i] + d;
                tot = tot + wt[i] * d;
            }

            mincost = MAXCOST;
            comp(1,n-1,2,n);

            System.out.println(mincost);
        }

    }

    private static void comp(int minp1, int maxp1, int minp2, int maxp2){
        int i,j,cost,opt=minp1;
        int optcost;
        if(minp1 >= minp2)
            minp2 = minp1 + 1;
        if(maxp1 >= maxp2)
            maxp1 = maxp2 - 1;
        if((minp1 > maxp1) || (minp2 > maxp2))
            return;

        optcost = MAXCOST;
        j = (minp2+maxp2)/2;

        for(i=minp1; i<=min(maxp1,j-1); i++){
            cost = getcost(i,j);
            if(cost < optcost){
                opt = i;
                optcost = cost;
            }
        }
        if(optcost < mincost)
            mincost = optcost;
        comp(minp1,opt,minp2,(minp2+maxp2)/2-1);
        comp(opt,maxp1,(minp2+maxp2)/2+1,maxp2);

    }

    private static int getcost(int i, int j){
        if(i > j)
            return 0;
        else
            return tot - wt[i] * (dist[j] - dist[i]) - wt[j] * (dist[n+1] - dist[j]);
    }

    private static int min(int a, int b){
        return a > b ? b : a;
    }
}

Input & Output

9
1 2
2 1
3 3
1 1
3 2
1 6
2 1
1 2
1 1
26

Reference

王晓东《计算机算法设计与分析》(第3版)P98-99

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值