zoukankan      html  css  js  c++  java
  • 【搜索】【动态规划】【杂题】——洛谷P1514.引水入城

    是一道十分巧妙的题目。

    GO:传送门


    首先考虑第一问:

      能否满足要求,用搜索遍历一下地图即可。

    难就难在第二问:如何求最小蓄水站数量?

      我们从河边开始走,从一个点(i,j)开始,由水流方向dfs,处理出每个节点到最底端最多能覆盖多长的一段路径。

      我们可以证明,如果有解,这段路径是连续的:

      如果不连续,那么在沙漠那块必定存在一个空间,使得不连续的那段路径将其包含,又知有解,所以必定存在一条路径使得那个空间与水源联通,与假设矛盾。  

      我们只要处理出水源处每一个点能到达的区间,然后做一个线段覆盖即可。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int N=510;
     4 int n,m;
     5 int val[N][N];
     6 int l[N][N],r[N][N];
     7 int vis[N][N];
     8 int px[5]{1,0,-1,0},py[5]{0,-1,0,1};
     9 struct sig{
    10     int a,b;
    11 }sg[N];
    12 bool cmp(sig x,sig y){
    13     return x.a>y.a;
    14 }
    15 void dfs(int x,int y){
    16     vis[x][y]=1;
    17     for(int i=0;i<=3;i++){
    18         int tx=x+px[i],ty=y+py[i];
    19         if(tx>n||tx<=0||ty>m||ty<=0) continue;
    20         if(val[tx][ty]<val[x][y]){
    21             if(!vis[tx][ty]) dfs(tx,ty);
    22             l[x][y]=min(l[x][y],l[tx][ty]);
    23             r[x][y]=max(r[x][y],r[tx][ty]);    
    24         } 
    25     }
    26 }
    27 int read(){
    28     int x=0,f=1;
    29     char c=getchar();
    30     while(!isdigit(c)){
    31         if(c=='-') f=-1;
    32         c=getchar();
    33     }
    34     while(isdigit(c)){
    35         x=x*10+c-'0';
    36         c=getchar();
    37     }
    38     return x*f;
    39 }
    40 int main(){
    41     n=read();m=read();
    42     for(int i=1;i<=n;i++){
    43         for(int j=1;j<=m;j++){
    44             val[i][j]=read();
    45         }
    46     }
    47     memset(l,0x3f,sizeof(l));
    48     memset(r,0,sizeof(r));
    49     for(int i=1;i<=m;i++){
    50         l[n][i]=r[n][i]=i;
    51     }
    52     for(int i=1;i<=m;i++){
    53         if(!vis[1][i]) dfs(1,i);
    54     }
    55     int sum=0;
    56     for(int i=1;i<=m;i++){
    57         if(!vis[n][i]) sum++;
    58     }
    59     if(sum){
    60         printf("0
    %d",sum);
    61         return 0;
    62     }
    63     int ll=1;
    64     while(ll<=m){
    65         int rr=0;
    66         for(int i=1;i<=m;i++){
    67             if(l[1][i]<=ll) rr=max(rr,r[1][i]);
    68         }
    69         sum++;
    70         ll=rr+1;
    71     }
    72     printf("1
    %d",sum);
    73     return 0;
    74 } 
    ——抓住了时间,却不会利用的人,终究也逃不过失败的命运。
  • 相关阅读:
    idea找不到或无法加载主类
    Scala核心编程_第09章 面向对象编程(高级特性)
    spring源码:学习线索
    Redis
    spring源码:Aware接口
    spring源码:核心组件(li)
    java socket编程
    spring源码:ApplicationContext的增强功能(li)
    spring源码:web容器启动
    spring源码:BeanPostProcessor(li)
  • 原文地址:https://www.cnblogs.com/Nelson992770019/p/11563140.html
Copyright © 2011-2022 走看看