嗯。。还是算法复习用到了的,竟然还有OJ上有这道题,所以过了一下
大体思路就是首先分点,记录同一位置不同剩余油量的花费。
int cost[N+1][N+1][K+1];
然后从起点开始一点一点扩展,分别判断有和没有加油站的情况走到4个方向上是否是更优的花费。有点儿类似Dijkstra最短路的感觉。
上代码
1 #include <iostream> 2 #include <queue> 3 #include <cstring> 4 #include <cstdio> 5 #include <cmath> 6 using namespace std; 7 #define ll long long 8 //template<typename T> 9 //inline T min(const T& a, const T& b) { return a < b? a:b;} 10 //template<typename T> 11 //inline T max(const T& a, const T& b) { return a > b? a:b;} 12 13 const int N = 100; 14 const int K = 10; 15 const int dirs[][2] = {{ -1, 0}, {1, 0}, {0, -1}, {0, 1}}; 16 17 struct Position 18 { 19 int x, y, k; 20 }; 21 22 queue<Position> que; 23 int cm[N + 1][N + 1][K + 1]; 24 int map[N + 1][N + 1]; 25 int inqueue[N + 1][N + 1][K + 1]; 26 int n, k, a, b, c; 27 28 bool isValid(int x, int y) 29 { 30 if(x < 1 31 || x > n 32 || y < 1 33 || y > n) 34 { 35 return false; 36 } 37 return true; 38 } 39 40 void init() 41 { 42 memset(cm, -1, sizeof(cm)); 43 cm[1][1][k] = 0; 44 memset(map, 0, sizeof(map)); 45 memset(inqueue, 0, sizeof(inqueue)); 46 while(!que.empty()) 47 { 48 que.pop(); 49 } 50 } 51 52 void checkBetter(int x, int y, int k, int cost) 53 { 54 // If is better to go to (x, y) from (p.x, p.y) 55 if(cm[x][y][k] == -1 || cm[x][y][k] > cost) 56 { 57 cm[x][y][k] = cost; 58 if(inqueue[x][y][k] == 0) 59 { 60 Position tem; 61 tem.x = x; 62 tem.y = y; 63 tem.k = k; 64 que.push(tem); 65 inqueue[tem.x][tem.y][tem.k] = 1; 66 } 67 } 68 } 69 70 int driveCar() 71 { 72 Position pos; 73 pos.x = pos.y = 1; 74 pos.k = k; 75 inqueue[1][1][k] = 1; 76 que.push(pos); 77 78 while(!que.empty()) 79 { 80 Position p = que.front(); 81 que.pop(); 82 inqueue[p.x][p.y][p.k] = 0; 83 for(int d = 0; d != 4; d++) 84 { 85 int dx = dirs[d][0], dy = dirs[d][1]; 86 int x = p.x + dx, y = p.y + dy; 87 88 if(isValid(x, y)) 89 { 90 int cost = cm[p.x][p.y][p.k]; 91 if(dx < 0) 92 { 93 cost += b; 94 } 95 if(dy < 0) 96 { 97 cost += b; 98 } 99 100 // No station. 101 if(p.k > 0 && map[p.x][p.y] == 0) 102 { 103 // If is better to go to (x, y) from (p.x, p.y) 104 checkBetter(x, y, p.k - 1, cost); 105 } 106 // Has station, ether a new built one, or one already exists. 107 cost += a; 108 if(map[p.x][p.y] == 0) 109 { 110 cost += c; 111 } 112 // Add fuel and check again 113 checkBetter(x, y, k - 1, cost); 114 } 115 } 116 } 117 118 int mincost = 0x7fffffff; 119 for(int i = 0; i <= k; i++) 120 { 121 if(cm[n][n][i] > 0 && mincost > cm[n][n][i]) 122 { 123 mincost = cm[n][n][i]; 124 } 125 } 126 return mincost; 127 } 128 129 int main() 130 { 131 #ifdef ACM_LOCAL 132 freopen("input.txt", "r", stdin); 133 //freopen("output.txt", "w", stdout); 134 #endif // ACM_LOCAL 135 136 while(scanf("%d%d%d%d%d", &n, &k, &a, &b, &c) != EOF) 137 { 138 init(); 139 140 for(int i = 1; i <= n; i++) 141 for(int j = 1; j <= n; j++) 142 { 143 scanf("%d", &map[i][j]); 144 } 145 146 printf("%d\n", driveCar()); 147 } 148 149 #ifdef ACM_LOCAL 150 printf("Used time: %lf\n", clock() / (double) CLOCKS_PER_SEC); 151 #endif // ACM_LOCAL 152 return 0; 153 }
速度还是挺快的:
Accepted
|
36MS
|
1128K
|
3449Byte
|
2013-12-23 15:11:43.0
|
不过Candesoft-BLOG里说的分层图最短路的没有仔细看。
来源:https://www.cnblogs.com/tech-cabin/p/Car_Drive_With_Fuel.html