题目大意:给出一张网格图,描述了每个点是否是加油站,然后给出以下规则。
1.油量限制,一次加油之后只能行驶k步,向下行驶和向右行驶的时候不增加花费,否则增加B的花费。
2.在没油的时候,若该点没有加油站,就建立一个加油站。花费C。
3.加油花费A。
思路:分层图。f[i][j][k]表示在(i,j)处油箱中还有k的油的时候的最小花费,然后分三种情况更新。
(delta = 往回走的B花费)
1.若当前节点有加油站,就必须加油。到下一个节点是还有k - 1的油量,花费last + A + delta
2.如果当前节点没有加油站,若当前车里还有油,就继续向下更新,花费last + delta
3.如果当前节点没有加油站,若当前车里没有油,就新建一个加油站,花费last + A + C + delta
CODE:
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 110
#define INF 0x3f3f3f3f
using namespace std;
const int dx[5] = {0,1,0,-1,0};
const int dy[5] = {0,0,1,0,-1};
struct Complex{
int x,y,odd;
Complex(int _,int __,int ___):x(_),y(__),odd(___) {}
Complex() {}
};
int cnt,k,add_oil,back_cost,new_cost;
int f[MAX][MAX][20];
bool v[MAX][MAX][20],map[MAX][MAX];
void SPFA();
int main()
{
cin >> cnt >> k >> add_oil >> back_cost >> new_cost;
for(int i = 1;i <= cnt; ++i)
for(int j = 1;j <= cnt; ++j)
scanf("%d",&map[i][j]);
SPFA();
int ans = INF;
for(int i = 0;i <= k; ++i)
ans = min(ans,f[cnt][cnt][i]);
cout << ans << endl;
return 0;
}
void SPFA()
{
memset(f,0x3f,sizeof(f));
f[1][1][k] = 0;
static queue<Complex> q;
while(!q.empty()) q.pop();
q.push(Complex(1,1,k));
while(!q.empty()) {
Complex now = q.front(); q.pop();
int last = f[now.x][now.y][now.odd];
v[now.x][now.y][now.odd] = false;
for(int i = 1;i <= 4; ++i) {
int detla = (i > 2) * back_cost;
int fx = now.x + dx[i];
int fy = now.y + dy[i];
if(!fx || !fy || fx > cnt || fy > cnt) continue;
if(map[now.x][now.y]) {
if(f[fx][fy][k - 1] > last + add_oil + detla) {
f[fx][fy][k - 1] = last + add_oil + detla;
if(!v[fx][fy][k - 1])
v[fx][fy][k - 1] = true,q.push(Complex(fx,fy,k - 1));
}
}
else {
if(!now.odd) {
if(f[fx][fy][k - 1] > last + add_oil + new_cost + detla) {
f[fx][fy][k - 1] = last + add_oil + new_cost + detla;
if(!v[fx][fy][k - 1])
v[fx][fy][k - 1] = true,q.push(Complex(fx,fy,k - 1));
}
}
else {
if(f[fx][fy][now.odd - 1] > last + detla) {
f[fx][fy][now.odd - 1] = last + detla;
if(!v[fx][fy][now.odd - 1])
v[fx][fy][now.odd - 1] = true,q.push(Complex(fx,fy,now.odd - 1));
}
}
}
}
}
}