Codeforces Round #323 (Div. 2)D lis

该博客介绍了一道编程竞赛题目,要求找到一个正整数数组在考虑重复元素后的最长非递减序列长度。输入包含两个整数n和T,以及n个正整数,当索引超过n时,元素值等于其n之前的值。解决方案涉及到找到前n个元素的最长递增子序列,并考虑当T大于n时如何利用重复序列来延长非递减序列。
摘要由CSDN通过智能技术生成

D. Once Again…
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard 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: n, T (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.

Examples
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小于等于n的部分的lis
看题干数据只要是nlgn跑个1e4是完全没有问题的…
问题在于后面…
只要t超过了n多余的部分可以理解为
把一个长为n的序列分成n个不同的部分
每个部分都是所有同样的长度
的和…
有些拗口..
所以可以理解为多余的部分是重复最多次的以达到最长的lis
并且从中间插入就可以了…

#include<iostream>
#include<algorithm>
#include<string>
#include<map>
#include<memory.h>
#include<queue>
using namespace std;
int tu[10001];
int dp[10001];
int tt[101];
int hs[301];
int main()
{
    int n, t;
    cin >> n >> t;
    int qq = min(t, n);
    for (int a = 1;a <= n;a++)cin >> tt[a];
    for (int a = 1;a <= qq;a++)for (int b = 1;b <= n;b++)tu[b + (a - 1)*n] = tt[b];
    int xc = n*qq;
//  memset(dp, 0x3f, sizeof(dp));
    dp[1] = tu[1];
    int cc = 1;
    int dd = tu[1];
    for (int a = 2;a <= xc;a++)
    {
        if (tu[a] >= dd)
        {
            dp[++cc] = tu[a];
            dd = dp[cc];
            continue;
        }
        int wew = upper_bound(dp + 1, dp + cc + 1, tu[a]) - dp;
        dp[wew ] = tu[a];
        dd = dp[cc];
    }
    int wew = 0;
    for (int a = 1;a <= n;a++)hs[tt[a]]++;
    int gs = 0;
    for (int a = 1;a <= 300;a++)gs = max(gs, hs[a]);
    if (t > n)cc += gs*(t - n);
    cout << cc << endl;
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值