POJ 2110 Mountain Walking 暴力搜索+二分
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 2110 Mountain Walking 暴力搜索+二分相关的知识,希望对你有一定的参考价值。
题意:n*n的矩阵 每次能走四个方向,定义路径的花费为:路径中方格的max-min,问从左上到右下的最小花费,n<=100
4个方向不是DAG,不能DP,暴力搜索 每个点最坏情况下走n*n 共n*n个点 O(n^4)TLE
二分ans后 枚举下界,则此时知道路径的最小值和最大值从
起点出发把mn<=c<=mx的点都遍历,此时dfs 相当于遍历图,不用回溯,复杂度为O(n^3*logn)
#include <iostream> #include <cstring> #include <cstdio> #include <cmath> #include <algorithm> #include <vector> using namespace std; typedef long long ll; typedef pair<ll,ll> ii; const int N=3e2+20; int n,ans,c[N][N],vis[N][N]; int dx[4]={-1,1,0,0}; int dy[4]={0,0,-1,1}; bool dfs(int x,int y,int mn,int mx) { if(c[x][y]>mx||c[x][y]<mn) return false; if(x==n&&y==n) return true; for(int i=0;i<4;i++) { int a=x+dx[i],b=y+dy[i]; if(a>=1&&a<=n&&b>=1&&b<=n&&!vis[a][b]) { vis[a][b]=1; if(dfs(a,b,mn,mx)) return true; } } return false; } void solve() { int l=0,r=110,ans; while(l<=r) { int mid=(l+r)>>1; bool flag=false; for(int i=0;i<=c[1][1];i++) { memset(vis,0,sizeof(vis)); vis[1][1]=1; if(dfs(1,1,i,i+mid)) { flag=true; break; } } if(flag) ans=mid,r=mid-1; else l=mid+1; } cout<<ans<<endl; } int main() { while(cin>>n) { ans=1e9; memset(vis,0,sizeof(vis)); for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { scanf("%d",&c[i][j]); } } solve(); } return 0; }
以上是关于POJ 2110 Mountain Walking 暴力搜索+二分的主要内容,如果未能解决你的问题,请参考以下文章
POJ 2977 Box walking 长方体表面两点距离
POJ 3162 Walking Race 树形dp 优先队列