『面试题』山西编程煤老板运煤

博客提出一个问题,山西煤老板有3000吨煤要运到1000公里外的市场,火车最多装1000吨且每公里耗1吨煤。题解指出可在1000公里中建立站点,用DP方法解决,假设在站点j能保证之前站点运到此处煤量最大,推导运到第i个站点的煤量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

『题目』:

  你是山西的一个煤老板,你在矿山区开采了有3000吨煤需要运送到市场上去卖,从你的矿区到市场有1000公里,你手里有一列烧煤的火车,这个火车最多只能装1000吨煤,且其能耗比较大----每一公里需要耗一顿煤,请问,作为一个懂编程的煤老板的你,你会怎么运送才能运最多的煤到集市。

『题解』:

 题意其实隐含着你可以在1000公里中建立站点的意思,最简单的思路是用DP方法,假设我现在在某个站点 j = 0... i − 1 j=0...i-1 j=0...i1,第 j j j 个站点保证从他之前的站点运到这里有最大的煤量,那么运到第 i i i 个站点又会有多少的煤呢?按照这个思想推导下去即可。

『实现』:

/**
 * Author:
 *      Gavinjou大笨象
 * Date:
 *      2019-05-01
 * Description:
 *      DP题
 */
public class job2 {
    //总共的公里数
    private static int m = 1001;
    //汽车的最大的运载能力
    private static int maxAbility = 1000;
    //总共的煤数
    private static int sum = 3000;

//    private static int m = 4;
//    private static int maxAbility = 5;
//    private static int sum = 30;
    private static int leave[];

    public static void main(String[] args) {

        int distance;
        leave=new int[m];
        toN1();
        leave[0]=sum;

        //当前节点是 i
        for(int i = 0;i < m;i++)
        {
            //前一个节点是 j
            for(int j = 0; j < i;j++)
            {
                //两个站点之间的距离
                distance = i - j;
                leave[i] = Math.max(leave[i],maxValue(-1,leave[j],distance));
            }
        }
        System.out.println("max ----> "+leave[m-1]);
    }

    private static void toN1()
    {
        for(int i = 0;i < m;i++)
        {
            leave[i] = -1;
        }

    }

    private static int maxValue(int sum1,int sum2,int distance)
    {
        int get;
        int ans = -1;

        //先运第一次,否则当前节点没有煤
        if( (sum2 - distance) >= 0)
        {
            get = Math.min(maxAbility,sum2);
            sum1 = get - distance;
            sum2 = sum2 -get;
            ans = sum1;
        }
        else return ans;


        while( (sum2 - distance) >= 0 && (sum1 - distance) >= 0)
        {
            //从【前一个节点】最多能装的货量
            get = Math.min(maxAbility,sum2);
            //减去【前一个节点】货量
            sum2 -= get;
            //加上【当前节点】的货量,同时还有来回距离的消耗量
            sum1 += (get - 2 * distance);
            //判断一下哪种情况获取的量最大
            ans = Math.max(ans,sum1);
        }

        return sum1;
    }

}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值