欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 养生 > D. Explorer Space(dfs+剪枝)

D. Explorer Space(dfs+剪枝)

2025/5/16 3:58:30 来源:https://blog.csdn.net/2302_79372568/article/details/147878964  浏览:    关键词:D. Explorer Space(dfs+剪枝)

Problem - 1517D - Codeforces 

题目大意:给你一个n行m列的矩阵,以及每个点上下左右相邻点的边权,求出每个点任意走k步后再回到当前这个点的最小路程,如果不能回到起始点则输出-1

思路:既然走k步后要回到起始点,则k一定要为偶数,若为奇数则每个点输出-1,否则我们只需要求从起始点走k/2步的最小路程,注意这里不能使用Dijkstra,因为可以重复走某些点,Dijkstra走过的点如果不进行标记容易超时,所以我们考虑使用dfs+记忆化,设置一个记忆化数组dp[i][j][c]表示(i,j)这个位置再走c步的最小路程。

Code:

int n,m,k;
map<PII,int> mp;
int dp[505][505][25];
int ne[4][2]={{0,1},{0,-1},{1,0},{-1,0}};int dfs(int x,int y,int c)
{if(c==0) return dp[x][y][c]=0;if(dp[x][y][c]) return dp[x][y][c];int mn=1e18;for(int i=0;i<4;i++){int tx=x+ne[i][0],ty=y+ne[i][1];if(tx>=1&&tx<=n&&ty>=1&&ty<=m){mn=min(mn,dfs(tx,ty,c-1)+mp[{(x-1)*m+y,(tx-1)*m+ty}]);}}return dp[x][y][c]=mn;
}
void solve()
{cin>>n>>m>>k;for(int i=1;i<=n;i++){for(int j=1;j<m;j++){int x;cin>>x;int a=(i-1)*m+j;int b=a+1;mp[{a,b}]=mp[{b,a}]=x; }}for(int i=1;i<n;i++){for(int j=1;j<=m;j++){int x;cin>>x;int a=(i-1)*m+j;int b=a+m;mp[{a,b}]=mp[{b,a}]=x;}}if(k&1){for(int i=1;i<=n;i++){for(int j=1;j<=m;j++) cout<<-1<<' ';cout<<endl;}return ;}k/=2;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){cout<<dfs(i,j,k)*2<<' ';}cout<<endl;}
}

 

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com