2020-04-20-从起点到终点城市的最小花费

题目描述

有N个城市,每个城市有传送门,城市i传送门通往城市a[i],当位于城市i,每次可以执行下列三个之一操作:

  • 花费A,从i到a[i]
  • 如果a[i] >1,可以花费B,将a[i]减小1
  • 如果a[i] <N,可以花费C,将a[i]增加1
    问从城市1,传送到N,最小花费?
    输入:第一行 N,A,B,C
    N是城市个数
    第2行 N个数字 表示a[1]~a[n]
    输出:最小花费
    案例 :
    7 1 1 1
    3 6 4 3 4 5 6
    输出:4

分析

  • 每次在某一个城市有三种选择,可以使用回溯法
  • 回溯尽头是访问到城市N

代码实现

import java.util.Scanner;

public class CityVisit {
    public static int minCost = 9999;
    public static int N = 7;
    public static int A = 1;
    public static  int B = 1;
    public static int C =1;
    public static int target = N;
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        N = sc.nextInt();
        A = sc.nextInt();
        B = sc.nextInt();
        C = sc.nextInt();
            //a[0] 不用
        int a [] = new int[N+1];
        for (int i = 1; i < a.length; i++) {
            a[i] = sc.nextInt();
        }
        //3 6 4 3 4 5 6
//            a[1] = 3;
//            a[2] = 6;
//            a[3] = 4;
//            a[4] = 3;
//            a[5] = 4;
//            a[6] = 5;
//            a[7] = 6;
            boolean visited [] = new boolean[N+1];
          helper(a,visited,1,0);
        System.out.println(minCost);
    }
    //index表示访问过几个城市 to表示去哪个城市 visited表示访问了几个 cost 表示成本
    public static void helper(int a[],boolean visited[],int to,int cost){
        if(to == N){
            if(cost < minCost){
                minCost = cost;
            }
            return;
        }else{
            //这一步去to城市 之前不能去过
            if(visited[to] || cost > minCost){
                return;
            }
            visited[to] = true;
            //直接过去
            helper(a,visited,a[to],cost+A);
            if(a[to] < N){
                helper(a,visited,a[to]+1,cost+C+A);
            }
            if(a[to] >1){
                helper(a,visited,a[to]-1,cost+B+A);
            }
            visited[to] = false;

        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值