NOIP2010引水入城题解

点击跟博主一起玩(zuo)耍(si)
首先这道题考验的并不是代码能力而是细心程度。仔细读题,你会发现对于每一个城市,如果要建水利设施,必须存在一个与它有公共边的比它高的城市才可以。运用贪心的算法,每次选取最高的靠近湖泊的城市进行搜索,当所有的干旱城市都建有水利设施的时候停止。当所有的靠近湖泊城市都建造了输水站而还有干旱城市没有满足条件时,需要for一遍干旱城市输出多少个没有建造水利设施。
那么接下来我们来证明一下贪心的正确性。
图
如上图。当干旱城市需要建造水利设施时一定存在一个有公共边的比它海拔高的城市。那么当从最高点开始搜索时,保证最少能覆盖一个靠近湖泊的城市,从而减少>=1个输水站的建造。
代码如下

#include<iostream>
#include<algorithm>
#include<cstring>

using namespace std;
struct factory{
     long l,r;
}p[501];

long n,m,map[501][501],f[501],cnt=0;

bool vis[501][501]={0},ans[501]={0};


bool comp(const factory &a,const factory &b)
{
    return a.l<b.l;
}

void dfs(long x,long y,long ori)
{
     vis[x][y]=1;
     if(x==m){
          ans[y]=1;
          p[ori].l=min(p[ori].l,y);
          p[ori].r=max(p[ori].r,y);
     }
     if(map[x+1][y]<map[x][y]&&x!=m&&!vis[x+1][y])dfs(x+1,y,ori);
     if(map[x-1][y]<map[x][y]&&x!=1&&!vis[x-1][y])dfs(x-1,y,ori);
     if(map[x][y+1]<map[x][y]&&y!=n&&!vis[x][y+1])dfs(x,y+1,ori);
     if(map[x][y-1]<map[x][y]&&y!=1&&!vis[x][y-1])dfs(x,y-1,ori);
}

int main()
{
     cin>>m>>n;
     for(long i=1;i<=n;++i)p[i].l=f[i]=30000;
     f[0]=0;
     for(long i=1;i<=m;++i)
          for(long j=1;j<=n;++j)cin>>map[i][j];
     for(long i=1;i<=n;++i){
          dfs(1,i,i);
          memset(vis,0,sizeof(vis));
     }
     for(long i=1;i<=n;++i)
          if(!ans[i])++cnt;
     if(cnt)cout<<0<<endl<<cnt;
     else{
          cout<<1<<endl;
          for(long i=1;i<=n;++i)
               for(long j=1;j<=n;++j){
                    if(i>=p[j].l&&i<=p[j].r)f[i]=min(f[i],f[p[j].l-1]+1);
              }
     cout<<f[n];
     }
     return 0;
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值