Contest 2050 and Codeforces Round #718 (Div. 1 + Div. 2)


傳送門

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("");
	}
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM