ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

引水入城

2020-03-07 16:56:44  阅读:274  来源: 互联网

标签:... ch int 引水 vis isdigit DP


引水入城

挺好的题..

首先可以思考到将第一行每一个点作为bfs的起点找出他能到的干旱地区,之后就想着状压...结果发现500根本压不下来...

那我们就要找点性质让我们可以DP....

之后就知道了每一个水库覆盖着干旱地区一定是连续的区间,因为如果连续,就一定会有交叉,之后就可以被一个水库代替...

这样我们就可以轻松DP了....

dp貌似可以线段树优化,管它呢,反正总复杂度O(n^3)了,就暴力DP吧..

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=510;
int h[N][N],n,m,dx[5]={-1,1,0,0},dy[5]={0,0,-1,1},f[N];
struct node{int l,r;}a[N];
bool vis[N][N];
inline int read()
{
    int x=0,ff=1;
    char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-') ff=-1;ch=getchar();}
    while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    return x*ff;
}
inline bool cmp(node x,node y) {return x.l<y.l;}
inline void bfs(int x,int y)
{
    queue<pair<int,int> >q;
    memset(vis,0,sizeof(vis));
    if(x==0&&y==0)
    {
        for(int i=1;i<=m;++i)
        {
            vis[1][i]=1;
            q.push({1,i});
        }
    }
    else vis[x][y]=1,q.push({x,y});
    while(!q.empty())
    {
        int t1=q.front().first;
        int t2=q.front().second;q.pop();
        for(int i=0;i<4;++i)
        {
            int xx=t1+dx[i];
            int yy=t2+dy[i];
            if(xx<1||xx>n||yy<1||yy>m) continue;
            if(h[xx][yy]<h[t1][t2]&&!vis[xx][yy]) 
            {
                vis[xx][yy]=1;
                q.push({xx,yy});
            }
        }
    }
}
int main()
{
    freopen("1.in","r",stdin);
    n=read();m=read();
    for(int i=1;i<=n;++i)
        for(int j=1;j<=m;++j) h[i][j]=read();
    bfs(0,0);
    int cnt=0;
    for(int i=1;i<=m;++i) if(vis[n][i]) cnt++;
    if(cnt!=m) {printf("%d\n%d",0,m-cnt);return 0;}
    for(int i=1;i<=m;++i)
    {
        bfs(1,i);
        for(int j=1;j<=m;++j) 
            if(vis[n][j])
            {
                if(!a[i].l) a[i].l=a[i].r=j;
                else a[i].r=j;
            } 
    }
    sort(a+1,a+m+1,cmp);    
    memset(f,0x3f,sizeof(f));
    f[0]=0;
    for(int i=1;i<=m;++i) 
    {
        if(a[i].l>=1)
        for(int j=a[i].l-1;j<a[i].r;++j) f[a[i].r]=min(f[a[i].r],f[j]+1);
    }
    printf("%d\n%d",1,f[m]);
    return 0;
}
View Code

 

标签:...,ch,int,引水,vis,isdigit,DP
来源: https://www.cnblogs.com/gcfer/p/12435259.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有