• codeforces#323(div2) D. Once Again... 求周期数列的LIS


    codeforces#323(div2) D. Once Again...   求周期数列的LIS

    D. Once Again...
    time limit per test
    1 second
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    You are given an array of positive integers a1, a2, ..., an × T of length n × T. We know that for any i > n it is true that ai = ai - n. Find the length of the longest non-decreasing sequence of the given array.

    Input

    The first line contains two space-separated integers: nT (1 ≤ n ≤ 100, 1 ≤ T ≤ 107). The second line contains n space-separated integers a1, a2, ..., an (1 ≤ ai ≤ 300).

    Output

    Print a single number — the length of a sought sequence.

    Sample test(s)
    input
    4 3
    3 1 4 2
    output
    5
    Note

    The array given in the sample looks like that: 3, 1, 4, 2, 3, 1, 4, 2, 3, 1, 4, 2. The elements in bold form the largest non-decreasing subsequence.

    这题有点乱搞的意味。。思考的过程应该是这样的:

    首先,先考虑T很大时,我们限定每个数只能用一次,那么LIS最多不会超过n,LIS所在的子数列长度最多也就是n*n,即每个周期都只选一个的情况,因此我们可以先求出n个周期的LIS。还剩下T-n个周期,这些周期可以插在LIS用到的那n个周期中间,这T-n个周期每个周期也要选一些数,那么选那些数呢,当然是选出现次数最多的!这样答案就是LIS(1,n*n)+(T-n)*max_cnt。

    上面是T>n的情况,对于T<=n的情况,直接求LIS即可,问题就此解决!

    完全不难啊。。。

    #include<bits/stdc++.h>
    #define REP(i,a,b) for(int i=a;i<=b;i++)
    #define MS0(a) memset(a,0,sizeof(a))
    
    using namespace std;
    
    typedef long long ll;
    const int maxn=1000100;
    const int INF=(1<<29);
    
    int n,T;
    int a[maxn];
    int b[maxn],len;
    int cnt[maxn];
    
    int lis(int *a,int n)
    {
        len=0;b[++len]=a[1];
        REP(i,2,n){
            if(a[i]>=b[len]) b[++len]=a[i];
            else{
                int p=upper_bound(b+1,b+len+1,a[i])-b;
                b[p]=a[i];
            }
        }
        return len;
    }
    
    int main()
    {
        while(cin>>n>>T){
            MS0(cnt);
            int max_cnt=0;
            REP(i,1,n) scanf("%I64d",&a[i]),cnt[a[i]]++,max_cnt=max(max_cnt,cnt[a[i]]);
            REP(i,1,n-1){
                REP(j,1,n){
                    a[i*n+j]=a[j];
                }
            }
            ll ans=0;
            if(T<=n) ans=lis(a,n*T);
            else{
                ans=lis(a,n*n)+max_cnt*(T-n);
            }
            printf("%I64d
    ",ans);
        }
        return 0;
    }
    View Code
    没有AC不了的题,只有不努力的ACMER!
  • 相关阅读:
    最全的静态网站生成器(开源项目)
    移动互联网流量变现模式调研问卷
    公众平台商户接入(微信支付)功能申请教程
    微信支付全面开放
    百度天气预报接口
    微信公众平台开发(83) 生成带参数二维码
    微信支付接口申请指南
    微信自媒体账号涉违规大规模被封
    php大文件上传解决方案支持分片断点上传
    html5大文件上传解决方案(500M以上)
  • 原文地址:https://www.cnblogs.com/--560/p/4857954.html
Copyright © 2020-2023  润新知