首页 > 代码库 > POJ 2110 Mountain Walking 暴力搜索+二分
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 暴力搜索+二分
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。