NJUPT 1362 汽车加油行驶问题

廉价感情. 提交于 2020-02-03 05:02:17

嗯。。还是算法复习用到了的,竟然还有OJ上有这道题,所以过了一下

参考是Candesoft-BLOG

大体思路就是首先分点,记录同一位置不同剩余油量的花费。

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 }
View Code

速度还是挺快的:


Accepted
36MS
  1128K
3449Byte
2013-12-23 15:11:43.0

不过Candesoft-BLOG里说的分层图最短路的没有仔细看。

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!