zoukankan      html  css  js  c++  java
  • 「LibreOJ β Round #4」子集

    https://loj.ac/problem/526

    题目描述

    qmqmqm有一个长为 n 的数列 a1,a2,,an,你需要选择集合{1,2,,n}的一个子集,使得这个子集中任意两个元素 i,j 均满足条件 gcd(ai,aj)×gcd(ai+1,aj+1)≠1,其中gcd(i,j)表示最大公约数,且这个子集的元素个数是所有满足上述条件的子集中最多的。输出这个子集的元素个数。

    输入格式

    输入的第一行包含一个正整数nnn。 随后nnn行,每行一个正整数aia_iai​​。

    输出格式

    输出一个整数代表符合条件的元素最多的子集的元素个数。

    样例

    样例输入1

    4
    4
    6
    1
    9

    样例输出1

    3

    样例解释

    选择的子集为{1,2,4}{1,2,4}{1,2,4}。

    样例输入2

    41
    71
    3
    5
    50
    75
    2
    19
    47
    88
    95
    92
    110
    111
    117
    58
    124
    130
    57
    129
    168
    161
    29
    39
    206
    79
    10
    142
    107
    209
    210
    222
    221
    223
    242
    104
    264
    265
    202
    279
    314
    315

    样例输出2

    22


    奇数和奇数、偶数和偶数一定可以选在一起
    所以对于不满足条件的奇数和偶数,连边
    求最大点独立集
    即点数-匹配数

    #include<cstdio>
    #include<iostream>
    #define N 501
    using namespace std;
    typedef long long LL;
    int n;
    LL a[N],b[N];
    bool g[N][N],vis[N];
    int match[N];
    void read(int &x)
    {
        x=0; int f=1; char c=getchar();
        while(!isdigit(c)) { if(c=='-') f=-1;  c=getchar(); }
        while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); }
        x*=f;
    }
    void read(LL &x)
    {
        x=0; int f=1; char c=getchar();
        while(!isdigit(c)) { if(c=='-') f=-1;  c=getchar(); }
        while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); }
        x*=f;
    }
    inline LL gcd(LL p,LL q) { return !q ? p : gcd(q,p%q); }
    bool go(int now)
    {
        for(int i=1;i<=b[0];i++)
        {
            if(vis[i] || !g[now][i]) continue;
            vis[i]=true;
            if(!match[i] || go(match[i]))
            {
                match[i]=now;
                return true;
            }
        }
        return false;
    }
    int main()
    {
        read(n);
        LL x;
        for(int i=1;i<=n;i++)
        {
            read(x);
            (x&1 ? a[++a[0]] : b[++b[0]])=x;
        }
        for(int i=1;i<=a[0];i++)
            for(int j=1;j<=b[0];j++)
                if(gcd(a[i],b[j])==1 && gcd(a[i]+1,b[j]+1)==1) g[i][j]=true;
        int sum=0;
        for(int i=1;i<=a[0];i++)
        {
            fill(vis+1,vis+b[0]+1,0);
            if(go(i)) sum++;
        }
        printf("%d",n-sum); 
    } 


  • 相关阅读:
    如何实现Appium每次运行可不用卸载手机上的Appium Settings 和Unlock
    jmeter参数化----绝对路径&相对路径
    python获取元素之byxpath()的八种方法
    uiautomatorviewer连接机器点击报错Unexpected error while obtaining UI hierarchy
    【Jmeter】使用 jmeter的_time函数获取时间
    博客作业第三周
    博客作业第二周
    博客作业第一周
    关于测试
    抽象工厂模式(AbstractFactory)
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/7468782.html
Copyright © 2011-2022 走看看