luoguP1514 引水入城
Posted dream-runner
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luoguP1514 引水入城相关的知识,希望对你有一定的参考价值。
一道挺水的记忆化搜索的题。。。
注意一个点即可,每个点衍生的河流只会在干旱区形成连续的一段,不会分成多个小段。
证明很简单- -
#include<bits/stdc++.h> using namespace std; const int maxn=510,inf=99999999; int l[maxn],r[maxn],tx[5]={0,1,-1,0,0},ty[5]={0,0,0,1,-1},a[maxn][maxn],n,m,f[maxn]; bool book[maxn][maxn],ans2[maxn]; typedef pair<int,int> P; P b[maxn][maxn]; P dfs(int x,int y){ P ret; ret.first=inf;ret.second=-inf; if(book[x][y])return b[x][y]; if(x==n){ ans2[y]=1; ret.first=l[y]; ret.second=r[y]; } book[x][y]=1; for(int i=1;i<=4;++i){ int xx=tx[i]+x,yy=ty[i]+y; if(xx<1||xx>n||yy<1||yy>m||a[xx][yy]>=a[x][y])continue; P t=dfs(xx,yy); ret.first=min(ret.first,t.first); ret.second=max(ret.second,t.second); } b[x][y]=ret; return ret; } int main(){ cin>>n>>m; for(int i=1;i<=n;++i){ for(int j=1;j<=m;++j)cin>>a[i][j]; } l[1]=1;r[m]=m; for(int i=2;i<=m;++i){ if(a[n][i-1]<a[n][i])l[i]=l[i-1]; else l[i]=i; } for(int i=m-1;i>=1;--i){ if(a[n][i+1]<a[n][i])r[i]=r[i+1]; else r[i]=i; } for(int i=1;i<=m;++i){ P t=dfs(1,i); if(t.first!=inf) f[t.first]=max(f[t.first],t.second); } int cnt=0; for(int i=1;i<=m;++i){ if(!ans2[i])++cnt; } if(cnt!=0){ cout<<0<<endl<<cnt; } else{ cout<<1<<endl; for(int i=1;i<=m;++i){ f[i]=max(f[i-1],f[i]); } int k=0,ans=0; while(k!=m){ k=f[k+1]; ++ans; } cout<<ans; } return 0; }
以上是关于luoguP1514 引水入城的主要内容,如果未能解决你的问题,请参考以下文章