3 条题解

  • 12
    @ 2023-8-1 16:50:57

    这段代码的思路是通过排序和最长不下降子序列算法来求解一组城市对中的最大匹配数。下面我将逐步解析代码。

    1. 定义了一个node结构体,用于存储每个城市对的北岸和南岸坐标。
    2. 声明了一个node类型的数组a[200005],用于存储输入的城市对信息。
    3. 定义了整数变量nilentemp,其中n表示城市对的数量,i用于循环迭代,len用于记录最长不下降子序列的长度,temp用于临时存储数据。
    4. 定义了一个自定义的比较函数cmp,用于排序时按照北岸坐标升序排列。
    5. main()函数中,首先使用scanf("%d", &n)读取城市对的数量。
    6. 接下来使用循环读取每个城市对的北岸和南岸坐标,并存储在相应的结构体数组a中。
    7. 使用sort函数对数组a进行排序,依据是北岸坐标的升序排列。
    8. 初始化最长不下降子序列数组d,将第一个城市对的南岸坐标放入数组中(即d[++len] = a[1].south)。
    9. 从第二个城市对开始,使用循环遍历剩余的城市对。
    10. 对当前城市对的南岸坐标,在最长不下降子序列数组d中查找合适的插入位置,并将其替换原来位置上的值。
    11. 如果当前城市对的南岸坐标在最长不下降子序列数组d的末尾插入,则更新最长不下降子序列长度len
    12. 最终得到的len即为最长不下降子序列的长度,输出结果。

    总结:该代码通过排序和最长不下降子序列算法,求解了一组城市对中的最大匹配数。它通过对北岸坐标的升序排列,将问题转化为求解南岸坐标的最长不下降子序列长度

    #include <stdio.h>
    #include <algorithm>
    using namespace std;
    
    struct node {
        int north;
        int south;
    };
    
    node a[200005];
    int n, d[200005], len;
    
    bool cmp(node x, node y) {
        return x.north < y.north;
    }
    
    int main() {
        if (scanf("%d", &n) != 1) {
            printf("Invalid input\n");
            return 0;
        }
        
        for (int i = 1; i <= n; i++) {
            if (scanf("%d %d", &a[i].north, &a[i].south) != 2) {
                printf("Invalid input\n");
                return 0;
            }
        }
        
        sort(a + 1, a + 1 + n, cmp);
        d[++len] = a[1].south;
    
        for (int i = 2; i <= n; i++) {
            int index = upper_bound(d + 1, d + len + 1, a[i].south) - d;
            d[index] = a[i].south;
            if (index > len) {
                len++;
            }
        }
    
        printf("%d", len);
        return 0;
    }
    
    • 6
      @ 2023-7-6 16:39:13

      输入是数据是乱序的,第一列数字表示南岸城市的位置,第二列数字是前面南岸城市对应在北岸的友好城市的位置,我们可以考虑使用结构体定义数组存储这些数据,并先根据其中一岸的位置先进行排序,假设先按照南岸城市的位置进行排序,要避免航道交叉,在选择北岸城市时需要大于上一个已批准的北岸城市的位置,这其实就转化成了LIS问题,我们只需要在北岸城市的序列中,找到一个最长上升的子序列,记录其最大长度,就是问题的解了。

      参考代码
      struct T
      {
      	int N,S;
      }c[200005];
      
      bool cmp(T x, T y)
      {
      return x.S < y.S;
      }
      
      sort (c + 1, c + n + 1, cmp);
          int ans = 0;
          for (int i = 1; i <= n; i++)
          {
              int now = lower_bound(d + 1, d + n + 1, c[i].N) - d;
              f[i] = now;
              d[now] = c[i].N;
              ans = max(ans, f[i]);
          }
      
      • 1
        @ 2024-1-19 21:07:20

        思路:先排序,再DP

        #include<bits/stdc++.h>
        using namespace std;
        struct city{
            int x,y;
        };
        bool cmp(city m,city n){
            return m.x<n.x;
        }
        int n,ans,len;
        int main(){
            cin>>n;
            int f[n+1],d[n+1];
            city a[n+1];
            memset(f,0,sizeof(f)),memset(d,0x3f,sizeof(d));
            for (int i=1;i<=n;i++)cin>>a[i].x>>a[i].y;
            sort(a+1,a+n+1,cmp);
            for (int i=1;i<=n;i++){
                int now=lower_bound(d+1,d+len+1,a[i].y)-d;
                f[i]=now,d[now]=min(d[now],a[i].y),ans=max(now,ans),len=max(len,now);
            }
            cout<<ans;
            return 0;
        }
        
        • 1

        信息

        ID
        270
        时间
        1000ms
        内存
        256MiB
        难度
        2
        标签
        (无)
        递交数
        536
        已通过
        324
        上传者