题意:
一辆车从起点走到终点,途中有些加油站,给出每个加油站距离和油价,最后求从起点到终点最小费用,其中在起点有100升油,要求到终点至少也还有100升油。
解法:
dp[i][j]记录走到第i站升j升油的最小费用,用当前的合法状态去更新后一个状态。
dp[i][j]表示到达第i个加油站剩余油量为j时的最小花费
特殊地,dp[n][j]表示到达终点剩余油量为j时的最小花费
状态转移:(设w[i]为每个加油站的位置,p[i]为油单价)
行驶:dp[i][j-(w[i]-w[i-1])] = dp[i-1][j] (0
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int INF = 0x3f3f3f3f;
char line[50];
int d[105],f[105];
int dp[105][205];
int dist;
int n;
int main() {
int T ,d1,f1;
scanf("%d",&T);
while(T--) {
scanf("%d",&dist); getchar();
n = 1;
while(gets(line) && line[0] != '\0') {
sscanf(line,"%d%d",&d1,&f1);
if(d1 > dist)
continue;
if(d[n-1] == d1 && f[n-1] < f1) //如果有两个相同的站点,且费用比前面的小
f[n-1] = f1;
else if(d[n-1]<d1) {
d[n]=d1;
f[n]=f1;
n++;
}
}
d[0] = 0;
d[n] = dist;
memset(dp,INF,sizeof(dp));
dp[0][100] = 0;
for(int i = 1; i <= n; i++) {
int dis = d[i] - d[i-1];
for(int j = dis; j <= 200; j++) {
dp[i][j-dis] = dp[i-1][j];
}
if(i != n)
for(int j = 1; j <= 200; j++) {
dp[i][j] = min(dp[i][j] , dp[i][j-1] + f[i]);
}
}
if(dp[n][100] != INF)
printf("%d\n",dp[n][100]);
else
puts("Impossible");
if(T)
printf("\n");
}
return 0;
}