解题的思路网上有很多文章。我犯的一个错误在于没有卡住油箱的上限只能是200,而用了一个更大一点的边界210,结果算出来的结果是更优的。代码写的不好,不过也懒得整理了。dp这一章的题目都ac了。
#include <iostream> #include <sstream> #include <fstream> #include <string> #include <vector> #include <list> #include <queue> #include <map> #include <set> #include <stack> #include <assert.h> #include <algorithm> #include <math.h> #include <ctime> #include <functional> #include <string.h> #include <stdio.h> #include <numeric> #include <float.h> using namespace std; const int MX_STATION_NUM = 110; const int MX_GAS = 201; const int MX_GAS_PRICE = 2000; int roadLength; vector<int> stations; vector<int> gasPrice; int dp[MX_STATION_NUM][MX_GAS]; int solution() { int n = stations.size(); for (int i = 0; i < n; i++) { for (int j = 0; j < MX_GAS; j++) { if (dp[i][j] >= 0) { for (int k = i + 1; k < n; k++) { int range = stations[k] - stations[i]; if (range > j) break; int left = j - range; for (int gas = left; gas < MX_GAS; gas++) { int money = (gas - left) * gasPrice[k] + dp[i][j]; if (dp[k][gas] == -1) { dp[k][gas] = money; } else { dp[k][gas] = min(dp[k][gas], money); } } } } } } int lastMile = roadLength - stations.back(); if (lastMile > 100) return -1; int result = dp[n-1][100 + lastMile]; for (int i = 101 + lastMile; i < MX_GAS; i++) { if (dp[n][i] >= 0) { result = min(result, dp[n][i]); } } return result; } int main(int argc, char* argv[]) { int T = 0; cin >> T; for (int t = 1; t <= T; t++) { for (int i = 0; i < MX_STATION_NUM; i++) { for (int j = 0; j < MX_GAS; j++) { dp[i][j] = -1; } } dp[0][100] = 0; stations.clear(); gasPrice.clear(); stations.push_back(0); gasPrice.push_back(MX_GAS_PRICE); string s; cin >> roadLength; getline(cin, s); while (getline(cin, s) && !s.empty()) { istringstream iss(s); int station, price; iss >> station >> price; stations.push_back(station); gasPrice.push_back(price); } int result = solution(); if (t > 1) cout << endl; if (result < 0) { cout << "Impossible" << endl; } else { cout << result << endl; } } return 0; }