题解 : 我们要注意到一个东西就是说一个序列复制 n 遍一定到 lis 最后一个要么是最大的元素,要么是这个序列中重复最多的元素,这样的话,我们对于 t < n 的情况直接暴力求 lis 就可以,对于 t > n 的情况,我们先复制n遍,再把剩下的出现最多的元素加入到这个序列中去就可以了.
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
const int maxn = 1e4 + 10;
int n,t;
int a[maxn] = {0};
int d[maxn] = {0};
int ans = 0;
int len = 0;
int cnt[maxn] = {0};
int mx = 0;
int main () {
ios_base :: sync_with_stdio(false);
cin >> n >> t;
for (int i = 1;i <= n; ++ i) {
cin >> a[i];
cnt[a[i]] ++;
mx = max (cnt[a[i]],mx);
}
int N;
if (t <= n) {
N = n * t;
}
else {
N = n * n;
}
for (int i = 1;i <= N; ++ i) {
if (i % n)
a[i] = a[i % n];
else a[i] = a[n];
}
int len = 1;
d[0] = a[1];
for (int i = 2;i <= N; ++ i) {
if (d[len - 1] <= a[i]) {
d[len ++] = a[i];
}
else {
int pos = upper_bound(d, d + len, a[i]) - d;
d[pos] = a[i];
}
}
ans = len;
if (t > n) {
ans += (t - n) * mx;
}
cout << ans << endl;
return 0;
}