zoukankan      html  css  js  c++  java
  • dtoj#4211. 一排数(array)

    题目描述:

    老虎和蒜头是好朋友。
    老虎最近得到了长度为 $n$ 的数列 $a$,对于一个数列,老虎定义了一个优秀度,其通过如下方式计算: 令 $x_1 = a_1,x_i = x_{i−1} mod a_i$,那么这个优秀度就是 $x_n$。 现在老虎想要知道在任意排列 $a$ 的情况下,最大的可能优秀度是多少。

    数据范围:

    对于 $100\%$ 的数据,$1 leq n , a _ { i } leq 10 ^ { 5 }$ 。

     算法标签:DP,二进制优化更新dp

    思路:

    首先取模操作只有比当前数小的才有用,所以我们呢可以把数从大往小排。

    如果最小的数只有一个,那么答案就是这个数字了,因为其他数在对最小的数取模最大也只能得到最小的数 $-1$ 的答案。

    其他情况我们可以把相同的数都去掉。

    $f[i][j]$ 表示经过前 $i$ 个数取模或不取模能否的都当前这个数 $j$ 。

    有两种转移:

    $if(f[i-1][j]==1)$

    $f[i][j]=1$  $f[i][jmod a[i]]=1$

    看到这个式子我们发现可以把第一维省去。

    然后对于每一次转移其实是以a[i]为单位每一块跟第一块取&,所以考虑二进制优化。

    以下代码:

    #include<bits/stdc++.h>
    #define il inline
    #define _(d) while(d(isdigit(ch=getchar())))
    using namespace std;
    const int N=1e5+5;
    bitset<N> f,h,g;
    int n,a[N],c[N],tot,mx;
    il int read(){
        int x,f=1;char ch;
        _(!)ch=='-'?f=-1:f;x=ch^48;
        _()x=(x<<1)+(x<<3)+(ch^48);
        return f*x;
    }
    bool cmp(int t1,int t2){return t1>t2;}
    il void work(int x,int y){
        g=f;
        for(int i=0;(i<<1)<=y;y-=(1<<i),i++)g|=g>>(x*(1<<i));
        if(y)g|=g>>x*y;
        f|=g&h;
    }
    int main()
    {
        n=read();
        for(int i=1;i<=n;i++)a[i]=read();
        sort(a+1,a+1+n,cmp);
        if(a[n]!=a[n-1]){printf("%d
    ",a[n]);return 0;}
        tot=unique(a+1,a+1+n)-a-1;mx=a[1];
        for(int i=0;i<mx;i++)h[i]=1;
        for(int i=1;i<=tot;i++)f[a[i]]=1;
        for(int i=1;i<=tot;i++){
            for(int j=a[i];j<a[i-1];j++)h[j]=0;
            work(a[i],mx/a[i]);
        }
        int ans=0;
        for(int i=mx-1;i;i--){
            if(f[i])ans=max(ans,i%a[tot]);
        }
        printf("%d
    ",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    基于Dubbo框架构建分布式服务(一)
    大型网站架构系列:消息队列
    Redis Cluster 分区实现原理
    Redis五种数据结构简介
    Java中创建对象的5种方式
    Netty 系列之 Netty 高性能之道
    Java 抽象类与接口
    谈iOS抓包:Mac下好用的HTTP/HTTPS抓包工具Charles
    Web系统大规模并发——电商秒杀与抢购
    [转]MS SQL Server 数据库连接字符串详解
  • 原文地址:https://www.cnblogs.com/Jessie-/p/10443187.html
Copyright © 2011-2022 走看看