解题的思路网上有很多文章。我犯的一个错误在于没有卡住油箱的上限只能是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;
}