转自kedebug大神:
题意:
有一辆车,原始装有100L汽油,到达距离为d的目的地,中间有x个加油站,每升油的价格为p。
汽车每跑一公里耗油1L,求到达目的地油箱仍然有100L的最小花费。
思路:
动归方程算是简单的,主要是要思考清楚,在第i个加油站加不加油,如果加油加k升的最小花费。
dp[i, j]表示在第i个加油站油箱有j升油的最小花费:
1. 在i站不加油 dp[i, j] = dp[i-1, j+di]; di为i-1到i的距离
2. 在i站加k升油 dp[i][j] = min(dp[i][j], dp[i-1][j-k+di] + k * p[i]);
初始状态为:dp[0, 100] = 0 其它的都是不可到达状态,赋值int_max
代码如下:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define INF 0x7fffffff #define M 210 #define N 110 int n, dp[N][M], d[N], p[N]; char s[N]; int main () { int t, l; scanf("%d",&t); while(t--) { scanf("%d",&n); getchar(); int l = 1; d[0] = 0; while(gets(s)) { if(strlen(s)==0) break; sscanf(s,"%d%d",&d[l],&p[l]); l++; } l-=1; for(int i = 0; i <= l; i++) for(int j = 0; j <= 200; j++) dp[i][j] = INF; dp[0][100] = 0; for(int i = 1; i <= l; i++) { int dis = d[i]-d[i-1]; for(int j = 0; j <= 200; j++) { if(j+dis<=200)dp[i][j] = dp[i-1][j+dis]; for(int k = 0; k<=j; k++) if(j+dis-k<=200&&dp[i-1][j+dis-k]!=INF)dp[i][j] = min(dp[i][j],dp[i-1][j+dis-k]+k*p[i]); } } if(100+n-d[l]>200||dp[l][100+n-d[l]]==INF) puts("Impossible"); else printf("%d\n",dp[l][100+n-d[l]]); if(t) puts(""); } return 0; }