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

这篇博客探讨了有向直线m中值问题,其中涉及到如何在一条有向直线上设置k个服务机构,以最小化服务转移费用。问题描述包括点的权值、边的长度和服务需求转移费用。文章提供了两个Java版本的实现,并给出了数据输入格式。

3-23 有向直线m中值问题


问题描述

给定一条有向直线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)。在点x0 处已设置了服务机构,现在要在直线 L 上增设 k 处服务机构,使得整体服务转移费用最小。

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

数据输入:
第 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: version 1

import java.util.Scanner;

public class YouXiangZhiXianMZhongZhi {

    private static int n,m;
    private static int[] dist,wt,swt;
    private static int[][] minco;

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

        while (true){
            n = input.nextInt();
            m = input.nextInt();

            dist = new int[n+2];
            wt = new int[n+1];
            swt = new int[n+1];
            minco = new int[n+1][m+1];

            dist[1] = 0;
            wt[0] = 0;
            swt[1] = 0;

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

            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;
                swt[i] = swt[i-1] + w * dist[i];
            }

            comp();

            System.out.println(minco[n][m]);
        }
    }

    private static void comp(){
        int i,j,k,tmp;
        for(i=1; i<=n; i++)
            minco[i][0] = getw(0,i+1);
        for(i=1; i<=n; i++)
            for(j=1; j<=m; j++){
                if(j >= i)
                    minco[i][j] = 0;
                else{
                    minco[i][j] = getw(1,i+1);
                    for(k=2; k<=i; k++){
                        tmp = minco[k-1][j-1] + getw(k,i+1);
                        if(tmp < minco[i][j])
                            minco[i][j] = tmp;
                    }
                }
            }
    }

    private static int getw(int i, int j){
        if(i > j)
            return 0;
        else
            return (wt[j-1] - wt[i]) * dist[j] - (swt[j-1] - swt[i]);
    }
}

Java: version 2

import java.util.Scanner;

public class YouXiangZhiXianMZhongZhi1 {

    private static int n,m;
    private static int[] dist,wt,swt;
    private static int[] minco;

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

        while (true){
            n = input.nextInt();
            m = input.nextInt();

            dist = new int[n+2];
            wt = new int[n+1];
            swt = new int[n+1];
            minco = new int[n+1];

            dist[1] = 0;
            wt[0] = 0;
            swt[1] = 0;

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

            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;
                swt[i] = swt[i-1] + w * dist[i];
            }

            comp();

            System.out.println(minco[n]);
        }
    }

    private static void comp(){
        int i,j,k,tmp;
        for(i=1; i<=n; i++)
            minco[i] = getw(0,i+1);

        for(j=1; j<=m; j++){
            for(i=n; i>j; i--){
                minco[i] = getw(1,i+1);
                for(k=2; k<=i; k++){
                    tmp = minco[k-1] + getw(k,i+1);
                    if(tmp < minco[i])
                        minco[i] = tmp;
                }
            }
            for(i=1; i<=j; i++)
                minco[i] = 0;
        }
    }

    private static int getw(int i, int j){
        if(i > j)
            return 0;
        else
            return (wt[j-1] - wt[i]) * dist[j] - (swt[j-1] - swt[i]);
    }

}

Input & Output

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

Reference

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值