D. Explorer Space
題意:給一個矩陣,告訴你每點相鄰邊的花費,求每個點k步后回到原點的最短距離。
題解:首先當k為奇數時,一定回不到原點直接輸出-1。當k為偶數時,可以理解為該點用了k/2步走了出去,又用k/2步走了回來,易知要距離最短所以出去和回來的路徑一定一樣,所以題目就轉化為了,走k/2步最少能用多少花費,直接記憶化即可。
#include<iostream>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
#define ll long long
const ll N=507;
const ll inf=1e18;
ll n,m,k,a[N][N],b[N][N],d[N][N][4],f[N][N][17];
ll dx[]={0,0,-1,1};
ll dy[]={1,-1,0,0};
ll dfs(ll x,ll y,ll k){
if(k==0){
return 0;
}
ll mi=inf;
if(f[x][y][k]!=-1){
return f[x][y][k];
}
for(int i=0;i<4;i++){
ll tx=x+dx[i];
ll ty=y+dy[i];
if(1<=tx&&tx<=n&&1<=ty&&ty<=m){
mi=min(mi,dfs(tx,ty,k-1)+d[x][y][i]);
}
}
return f[x][y][k]=mi;
}
ll gao(ll x,ll y){
if(k%2==1){
return -1;
}
else{
return dfs(x,y,k/2)*2;
}
}
int main(){
memset(f,-1,sizeof(f));
scanf("%lld%lld%lld",&n,&m,&k);
for(int i=1;i<=n;i++){
for(int j=1;j<m;j++){
scanf("%lld",&a[i][j]);
d[i][j][0]=a[i][j];
d[i][j+1][1]=a[i][j];
}
}
for(int i=1;i<n;i++){
for(int j=1;j<=m;j++){
scanf("%lld",&b[i][j]);
d[i][j][3]=b[i][j];
d[i+1][j][2]=b[i][j];
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
printf("%lld ",gao(i,j));
}puts("");
}
}