zoukankan      html  css  js  c++  java
  • AcWing 1012. 友好城市

    题目传送门

    一、题目分析

    条件一:每个城市只能建立一座桥

    条件二:所有的桥与桥之间不能相交

    目标:最多能建立多少座桥

    步骤

    1. 通过排序,固定自变量的顺序

    2. 找因变量的最大上升子序列。(原因:找出的上升子序列越长,与下面自变量的匹配数量就越大,也就是修的桥数越多。)

    总结:

    • 本题还是有一些思维的难度,需要对问题进行转化。用数对描述问题比较好想,为什么要按左端点进行排序呢?似乎对于数对而言,大多数情况需要固定一个端点,比如区间合并,如果我们能想到这是一个用数对描述的问题,不妨先想一下是不是在按左端点排序一下。

    • 按左端点排序后,一般的思路就是对比右端点(要不按左端点排序就没啥意义了~)。此时就是把二维的概念转化为一维的概念。本题是根据右端点的逆序关系来说明当前路线与前序的矛盾关系,我们把图画出来,现在聚焦到一维上面(就是是图的上侧),发现,如果是严格单调上升的序列,越长的话,修建的桥数越多。

    • \(lis\)的原问题出发,思考以上方的每一个数字结尾,会产生多少座桥,也就是问题的答案。

    • 思考一个复杂问题,从有一定的套路,将问题进行转化,然后再从最朴素的模板问题出发,思考问题的本质。

    二、实现代码

    #include <bits/stdc++.h>
    
    using namespace std;
    //线段,二维,一般用PII,因为可以不需要写cmp,直接按first排序
    typedef pair<int, int> PII;
    
    const int N = 5010;
    PII a[N];   //南岸和北岸的一对友好城市的坐标
    int f[N];   //记录以f[i]为结尾的一对友好城市时的,不产生交叉的最多城市对数
    int n;      //n组友好城市
    
    int main() {
        cin >> n;
        //读入友好城市对
        for (int i = 1; i <= n; i++)cin >> a[i].first >> a[i].second;
        //按first排序,则南岸城市坐标由小到大
        sort(a + 1, a + 1 + n);
    
        int mx = 0;
        //LIS 正向
        for (int i = 1; i <= n; i++) {
            f[i] = 1;
            for (int j = 1; j < i; j++)
                //如果南岸城市坐标由小到大,那么北岸也必须由小到大,否则就是交叉
                if (a[i].second > a[j].second)
                    f[i] = max(f[i], f[j] + 1);
            mx = max(mx, f[i]);
        }
        printf("%d\n", mx);
        return 0;
    }
    
  • 相关阅读:
    9 与python2交互
    8 内置函数(未完成)
    7 事务
    [转]jquery.vTicker(垂直滚动)
    2015年工作总结(2016-02-02)
    jQuery plugin : jqTransform
    JQuery知识总结
    JQuery事件处理的注意事项
    JQuery基本选择器
    [二]JQueryMobile常用的组件介绍
  • 原文地址:https://www.cnblogs.com/littlehb/p/15649075.html
Copyright © 2011-2022 走看看