题意:
租了一俩车从城市A到城市B,开始有100L油,油箱总共可以装200L油,行驶1KM要1L油,路上有加油站,离A有不同的距离,每升油价格不同。
问,到城市B油箱还有100L油,最少的花费是多少。
dp[i][j] 表示在站点 i 有油 j 时的最小花费。那么
dp[i][j] = min(dp[i-1][j+d[i]],dp[i][j]),d[i] 表示 i-1到i的距离。
dp[i][j]有俩个来源,一个是从dp[i-1][j+d[i]],dp[i][j]表示在站点i加油到j 的花费。
import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileNotFoundException; import java.util.Scanner; public class Main { static Scanner scanner; final static int G = 110; // final static int G = 8; final static int T = 206; // final static int N = 5; // dij表示在i站点gas是j的时候最小花费 static int[][] dp = new int[G][T]; static int dis; static int[] sd = new int[G]; static int[] sp = new int[G]; static int[] disSum = new int[G]; static int gt; static int INF = Integer.MAX_VALUE; static int maxDis = -1; static int tt = 1; public static void main(String[] args) throws FileNotFoundException { scanner = new Scanner(System.in); //scanner = new Scanner(new File("/Users/caicai/in")); String str = scanner.nextLine(); int val = Integer.valueOf(str); // empty line tt = 1; while (val-- != 0) { gt = 1; maxDis=-1; dis = scanner.nextInt(); sd[0] = 0; sp[0] = 0; int preDis = 0; str = scanner.nextLine(); while (scanner.hasNextLine()) { // split str = scanner.nextLine(); if (str.isEmpty()) { break; } ByteArrayInputStream si = new ByteArrayInputStream(str.getBytes()); Scanner scanner2 = new Scanner(si); int diss = scanner2.nextInt(); int price = scanner2.nextInt(); scanner2.close(); if (diss > dis) continue; sd[gt] = diss - preDis; preDis = diss; sp[gt] = price; ++gt; if (diss > maxDis) maxDis = diss; } // dp dp(); } } static void init() { for (int i = 0; i < G; i++) { for (int j = 0; j < T; j++) { if (i == 0 || j == 0) dp[i][j] = INF - 1; else dp[i][j] = INF; } } } static void dp() { init(); if (sd[1] > 100) { if (tt != 1) System.out.println(); System.out.println("Impossible"); ++tt; return; } dp[1][100 - sd[1]] = 0; // 多余的gas int h = 100 - sd[1]; for (int i = h; i >= 0; i--) { dp[1][i] = (h - i) * -1 * sp[1]; } for (int i = 1; i < gt; i++) { for (int j = 0; j <= 200; j++) { // 当前的站点gas是j int diss = sd[i]; if (diss + j > 200 || dp[i - 1][diss + j] == INF) { continue; } dp[i][j] = Math.min(dp[i - 1][diss + j], dp[i][j]); for (int k = j + 1; k <= 200; k++) { // 当前站点加到k气要的钱 int curPrice = sp[i] * (k - j) + dp[i][j]; dp[i][k] = Math.min(dp[i][k], curPrice); // if (diss + k > 200) continue; // int preCurPrice = dp[i - 1][diss + k]; // dp[i][k] = Math.min(dp[i][k], preCurPrice); } } } // check val int half = 100; // 检查最后一个站点 int lastDis = dis - maxDis; int gas = lastDis + half; if (gas > 200 || dp[gt - 1][gas] == INF) { if (tt != 1) System.out.println(); System.out.println("Impossible"); ++tt; return; } else { if (tt != 1) System.out.println(); ++tt; System.out.println(dp[gt - 1][gas]); } } }