码迷,mamicode.com
首页 > 其他好文 > 详细

luoguP1514 引水入城

时间:2018-10-19 21:58:03      阅读:174      评论:0      收藏:0      [点我收藏+]

标签:continue   clu   type   isp   return   搜索   注意   space   def   

一道挺水的记忆化搜索的题。。。

注意一个点即可,每个点衍生的河流只会在干旱区形成连续的一段,不会分成多个小段。

证明很简单- - 

技术分享图片
#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;
}
View Code

 

luoguP1514 引水入城

标签:continue   clu   type   isp   return   搜索   注意   space   def   

原文地址:https://www.cnblogs.com/Dream-Runner/p/9818643.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!