您的位置:首页 > 大数据 > 人工智能

Codeforces Round #323 (Div. 1) B. Once Again... 最长非严格递增子序列

2015-10-05 18:07 691 查看
B. 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.

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.

题意,要求循环数列的最长非递增子序列。

如果,周期是足够大的(大于 2 * n),那么怎样才能最长呢,无疑会出现中间有一段是平的,也就是一个周期内出现次数最多的那个数。因为,一个周期最多有n个不同的数,要求的数列又是递增的,达到n个后,还有更多的,肯定是有重复的数。

就像如图所示



所示的n1 n2最长是n段周期。所以,我们可以先把前n * n个数,后n * n 个数算出最长非严格递增子序列。中间那段就是,一个周期出现最多的次数* (T - 2 * n);

时间复杂度为n * n log (n * n);

下面用两种方式求,

第一种,直接用dp推,由于是周期的数列,所以,可以优化到o(n * n * n)的复杂度。

第二种,就直接用二分查找的方法,优化求非递增子序列的方法。

主要思想就是,用一个数组维护一个递增的子序列,如果,新加的无素大于,最后一个无素,直接加入,否则,在数组里,把第一个大于新加的元素的元素更新就可以了。复杂度为o(n * n * log(n * n));

#define N 100005
#define M 100005
#define maxn 205
#define MOD 1000000000000000007
int n,T,dp
,num[400],b
,a
,an;
int Find2(int bn){
FI(bn) dp[i] = 1;
int maxx = 0;
FI(bn){
int s = min(i,n);
for(int j = 1;j<=s;j++){
if(b[i - j] <= b[i]){
dp[i] = max(dp[i],dp[i - j] + 1);
}
}
maxx = max(maxx,dp[i]);
}
return maxx;
}
int Find1(int bn){
an = 0;
FI(bn){
if(an <= 0 || b[i] >= a[an - 1]){
a[an++] = b[i];
}
else {
int k = (upper_bound(a,a+an,b[i]) - a);
a[k] = b[i];
}
}
return an;
}
int main()
{
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
while(S2(n,T)!=EOF)
{
fill(num,0);
int mn = 0;
FI(n){
S(b[i]);
num[b[i]]++;
mn = max(mn,num[b[i]]);
}
if(T <= 2 * n){
int bn = n * T;
FI(bn){
b[i] = b[i % n];
}
printf("%d\n",Find1(bn));
}
else {
int bn = n * 2 * n;
FI(bn){
b[i] = b[i % n];
}
printf("%d\n",mn * (T - 2 * n) + Find1(bn));
}
}
//fclose(stdin);
//fclose(stdout);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  codeforces