P4009 汽车加油行驶问题
紫题,但是DFS
。
思路
记忆化搜索,分多钟情况去搜索。
注意该题不用标记,有可能会往回走。
有可能这样走。
代码
#include<bits/stdc++.h>
#include<cstring>
#include<queue>
#include<set>
#include<stack>
#include<vector>
#include<map>
#define ll long long
#define lhs printf("\n");
using namespace std;
const int N=1e5+10;
const int M=2024;
const int inf=0x3f3f3f3f;
ll n,a,b,c,d,k;
ll g[114][114];
ll ans=inf;
int dx[]={1,0,0,-1};
int dy[]={0,1,-1,0};
ll vis[114][114];
ll v[114][114][20];
int mp[114][114];
int flag;
/*
x,y当前位置
num剩余步数
step总花费
*/
void dfs(ll x,ll y,ll num,ll step)
{
if(x==n and y==n)//找到答案
{
ans=min(ans,step);
return;
}
if(v[x][y][num]<=step)return;//记忆化
v[x][y][num]=step;
if(step>=ans)return;
for(int i=0;i<4;i++)
{
int l=0;
int nx=x+dx[i];
int ny=y+dy[i];
if(i==3 or i==2)//往回走的话就要+b
{
l=b;
}
if(nx>=1 and nx<=n and ny>=1 and ny<=n and vis[nx][ny]==0 and num>=1)
{
// vis[nx][ny]=1;
// 这里不用标记,因为有可能往回走
if(g[nx][ny]==0 and num==1)//不是加油站,但是没油了
{
//建一个加油站,并加油
g[nx][ny]=1;
dfs(nx,ny,k,step+c+a+l);
g[nx][ny]=0;
//按理来说是走不了,但是万一下一步是终点呢?大不了就是退回来
dfs(nx,ny,num-1,step+l);
}
else if(g[nx][ny]==1)//加油站必须加油
{
dfs(nx,ny,k,step+a+l);
}
else if(g[nx][ny]==0 and num!=1)//剩余情况就直接走
{
dfs(nx,ny,num-1,step+l);
}
// vis[nx][ny]=0;
}
}
}
int main()
{
memset(v,inf,sizeof v);
cin>>n>>k>>a>>b>>c;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
cin>>g[i][j];
}
}
dfs(1,1,k,0);
cout<<ans;
return 0;
}