• “玲珑杯”ACM比赛 Round #11 B -- 萌萌哒的第二题


    DESCRIPTION

    一条东西走向的河两边有都排着工厂,北边有n间工厂A提供原材料,南边有n间工厂B进行生产。现在需要在工厂A和工厂B之间建运输桥以减少运输成本。可是每个工厂B只能接受最多6个工厂A提供的材料能满足生产,而且建立的运输桥之间不能有交叉,北边的工厂A由西向东编号1~n,南边的工厂B也是一样,不能交叉的意思是如果a号工厂A跟b号工厂B之间建立了运输桥,那么不能存在c、d(c < a 且d > b) 使得c号工厂A和d号工厂b之间建立运输桥,每个工厂A只能给一个工厂B提供材料,每个工厂B只能由一间工厂A提供材料,请问在满足上述条件的情况下最多能建立多少个运输桥。
    (每个工厂最多有6个选择,但只能选一个)

    INPUT
    包含多组测试数据(<=15),其中每组测试数据: 第一行一个整数n(1<= n <= 10^5) 接下来n行,第i+1行6个整数表示i号工厂B能接受的6个工厂A的编号,保证所有编号的范围是1~n,可能重复(请看样例)。
    OUTPUT
    每组数据输出一行一个整数表示最多能建立的运输桥数量。
    SAMPLE INPUT
    3
    1 2 3 1 2 3
    2 2 2 2 2 2
    1 3 1 3 1 3
    6
    1 2 3 4 5 6
    1 2 3 4 5 6
    1 2 3 4 5 6
    1 2 3 4 5 6
    1 2 3 4 5 6
    1 1 1 1 1 1
    SAMPLE OUTPUT
    3
    5

     一道简单的dp,dp[i]表示建了i座桥最小a的编号是多少。

    有点类似lis。遍历b,而后每一个b能链接的a点在dp中用二分查找。注意将b链接的a从大到小排序一下。

    二分可用upper_bound来查找,找到pos点后先于pos-1位置的dp值比较一下因为有可能dp[pos-1]的值

    与查询的值一样这样pos点就不更新,反之更新一下。

    #include <iostream>
    #include <cstring>
    #include <string>
    #include <cstdio>
    #define inf 0X3f3f3f3f
    using namespace std;
    const int M = 1e5 + 10;
    int a[M][8] , dp[M];
    bool cmp(int x , int y) {
        return x > y;
    }
    int main() {
        int n;
        while(~scanf("%d" , &n)) {
            for(int i = 1 ; i <= n ; i++) {
                for(int j = 0 ; j < 6 ; j++) {
                    scanf("%d" , &a[i][j]);
                }
                sort(a[i] , a[i] + 6 , cmp);
            }
            for(int i = 0 ; i <= n ; i++) {
                dp[i] = inf;
            }
            for(int i = 1 ; i <= n ; i++) {
                for(int l = 0 ; l < 6 ; l++) {
                    int p = upper_bound(dp + 1 , dp + 1 + n , a[i][l]) - dp;
                    if(dp[p - 1] == a[i][l])
                        continue;
                    else
                        dp[p] = min(dp[p] , a[i][l]);
                }
            }
            int MAX = 1;
            for(int i = n ; i >= 1 ; i--) {
                if(dp[i] != inf) {
                    MAX = i;
                    break;
                }
            }
            printf("%d
    " , MAX);
        }
        return 0;
    }
    
  • 相关阅读:
    线程死的时候会调用自己的notifyAll方法,join会执行结束。
    NIO中SocketChannel read()返回0的原因
    用bytebuffer进行文件的读写代码段
    java线程池参数含义
    4.3list集合
    4.1、2集合框架介绍
    3.9stingBuffer和stringBuilder
    3.8正则表达式
    3.6、7正则表达式
    3.3、4深度了解字符串
  • 原文地址:https://www.cnblogs.com/TnT2333333/p/6501860.html
Copyright © 2020-2023  润新知