题目描述
有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;
}
}
}