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;
}
AC记录