现在做动归还是没有什么思路,基本靠“蒙”,先假设状态,然后再去找状态转移方程,最后再修修补补。今天能做出这道题来感觉还是很兴奋的。
定义状态:f[i][j]表示在第i距离处车里还剩j升油所需的最小花费,如果能后到达终点,答案就是f[length][100];状态转移方程:f[i][j] = min(f[i][j], f[i-1][k] + (j - k) * m[i]);这里i-1表示i车站的前边的一个车站所在的位置,0<=k<j;还有f[i][j] = min(f[i][j], f[i - 1][j + w(i) - w(i - 1));复杂度为:O(100 * 200 *200);注意:有些车站可能在所要求的距离之外,这样的车站就不要了
#include <iostream> #include <cstdio> #include <cstring> #include <utility> using namespace std; #define x first #define y second const int INF = (1<<29); typedef pair<int, int> pii; pii p[110]; int f[10010][210]; char s[100]; int main() { //freopen("input.txt", "r", stdin); int nCase; int leng, n, unsucc; scanf("%d", &nCase); while(nCase--){ scanf("%d", &leng); getchar(); n = 1; p[0].x = p[0].y = 0; unsucc = 0; while(gets(s)){ if(strlen(s)){ sscanf(s, "%d %d", &p[n].x, &p[n].y); if(n > 1){ if(p[n].x - p[n - 1].x > 200) unsucc = 1; }else { if(p[n].x > 100) unsucc = 1; } if(p[n].x <= leng) n++; }else break; } if(leng - p[n - 1].x > 100) unsucc = 1; if(unsucc){ printf("Impossible\n"); }else{ for(int i = 0; i <= leng; i++) for(int j = 0; j <= 200; j++) f[i][j] = INF; f[0][100] = 0; int up; for(int i = 1; i < n; i++){ for(int j = 0; j <= 200; j++){ if(j + p[i].x - p[i - 1].x <= 200) f[p[i].x][j] = min(f[p[i].x][j], f[p[i - 1].x][j + p[i].x - p[i - 1].x]); for(int k = 0; k < j; k++){ f[p[i].x][j] = min(f[p[i].x][j], f[p[i].x][k] + (j - k) * p[i].y); } } } if(f[p[n - 1].x][100 + (leng - p[n - 1].x)] != INF) printf("%d\n", f[p[n - 1].x][100 + (leng - p[n - 1].x)]); else printf("Impossible\n"); } if(nCase) printf("\n"); } return 0; }
10201 - Adventures in Moving - Part IV
最新推荐文章于 2016-07-07 01:21:49 发布