• 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("");
    	}
    }
    
  • 相关阅读:
    strcpy ,strncpy ,strlcpy(转载)
    窗口刷新时的问题(转)
    Linux下的实时流媒体编程(RTP,RTCP,RTSP)
    YUV色彩空间(转自百度百科)
    VC++2005快速构建安全的应用程序
    Linux多线程编程
    C++ PASCAL关键字(转)
    SkinMagic 进行皮肤设置
    .h和.cpp文件的区别
    strcpy_s与strcpy安全性的比较(转载)
  • 原文地址:https://www.cnblogs.com/whitelily/p/14696086.html
Copyright © 2020-2023  润新知