POJ 2110 Mountain Walking 暴力搜索+二分
阿新 • • 發佈:2017-06-07
brush pac 情況 cnblogs typedef main lag highlight bool
題意: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 暴力搜索+二分