1. 程式人生 > >luogu P4009 汽車加油行駛問題

luogu P4009 汽車加油行駛問題

luogu P4009 汽車加油行駛問題
網路流!
(可惜我不會)
最短路!
(可惜我打不好)
dp!
(可惜碼量太大)
BFS!
(終於來一哥麼兒可寫)
大力一發BFS
記憶化:
f[i][j][k]表示到達i,j這個點,油量還有j的最小花費
然後應該沒人會傻到油沒用完就去建油庫的~
記住:自己建油庫的花費=油庫花費+加油花費!
(否則你建了油庫不加油,傻麼?)
還有:到了終點你不管有油沒油、有油站沒油站都不花錢!
然後這些細節注意了,就沒啥大問題了。
BMH OJ卡空間,要用迴圈佇列
(舉手之勞,你幹我幹大家幹)
不要忘記人家往上或左走是要收費的!
答案在f[n][n][i:1->k]裡!
std:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct node
{
    int x;
    int y;
    int las;
    ll mon;
};
const int N=205;
int n,k;
ll a,b,c;
bool u[N][N];
ll f[N][N][15];
node q[5000000];
int head=1,tail=1;
ll h=1,t=1;
int dx[4]={1,0,0,-1};
int dy[4]={0,1,-1,0};
ll cs[4]={0,0,1,
1}; ll ans=2110920147483647; int main() { memset(f,127,sizeof(f)); scanf("%d%d%lld%lld%lld",&n,&k,&a,&b,&c); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) scanf("%d",&u[i][j]); q[1].x=1,q[1].y=1,q[1].las=k,q[1].mon=0; while(h<=t) {
node r=q[head]; for(int i=0;i<4;i++) { node v=r; v.x+=dx[i]; v.y+=dy[i]; v.mon+=cs[i]*b; v.las--; if(v.x<1||v.x>n||v.y<1||v.y>n) continue; if(v.x==n&&v.y==n){ f[v.x][v.y][v.las]=min(f[v.x][v.y][v.las],v.mon); continue; } if(u[v.x][v.y]) { v.las=k; v.mon+=a; } else if(v.las==0) { v.las=k; v.mon+=c+a; } bool flag=0; for(int i=v.las;i<=k;i++) { if(f[v.x][v.y][v.las]<=v.mon) { flag=1; break; } } if(!flag) { f[v.x][v.y][v.las]=v.mon; tail++; if(tail==50000000) tail=1; t++; q[tail]=v; } } head++; if(head==50000000) head=1; h++; } for(int i=0;i<=k;i++) ans=min(ans,f[n][n][i]); printf("%lld\n",ans); return 0; }