【CF】323 Div2. D. Once Again...

时间:2023-03-08 15:53:49

挺有意思的一道题目。
考虑长度为n的数组,重复n次,可以得到n*n的最长上升子序列。同理,也可以得到n*n的最长下降子序列。
因此,把t分成prefix(上升子序列) + cycle(one integer repeating) + sufix(下降子序列)。
当t<=2*n时,暴力解。
注意数据范围。

 /* 583D */
#include <iostream>
#include <string>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
#include <deque>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstring>
#include <climits>
#include <cctype>
#include <cassert>
#include <functional>
#include <iterator>
#include <iomanip>
using namespace std;
//#pragma comment(linker,"/STACK:102400000,1024000") #define sti set<int>
#define stpii set<pair<int, int> >
#define mpii map<int,int>
#define vi vector<int>
#define pii pair<int,int>
#define vpii vector<pair<int,int> >
#define rep(i, a, n) for (int i=a;i<n;++i)
#define per(i, a, n) for (int i=n-1;i>=a;--i)
#define clr clear
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define all(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1 const int maxn = ;
const int maxm = ;
int c[maxm];
int a[maxn], b[maxn*maxn*];
int dp[maxm];
int suf[maxn*maxn], pre[maxn*maxn]; int main() {
ios::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif int n, t;
int mx;
int ans = ; scanf("%d %d", &n, &t);
rep(i, , n+) {
scanf("%d", &a[i]);
++c[a[i]];
} if (t <= n*) {
rep(i, , n+) {
int k = i;
rep(j, , t+) {
b[k] = a[i];
k += n;
}
} int n_ = n*t; memset(dp, , sizeof(dp));
rep(i, , n_+) {
mx = ;
rep(j, , b[i]+)
mx = max(mx, dp[j]);
pre[i] = ++mx;
dp[b[i]] = mx;
}
rep(i, , n_+)
ans = max(ans, pre[i]);
printf("%d\n", ans);
return ;
} rep(i, , n+) {
int k = i;
rep(j, , n+) {
b[k] = a[i];
k += n;
}
} // calculate prefix
int n_ = n*n; memset(dp, , sizeof(dp));
rep(i, , n_+) {
mx = ;
rep(j, , b[i]+)
mx = max(mx, dp[j]);
pre[i] = ++mx;
dp[b[i]] = mx;
} // calculate suffix
memset(dp, , sizeof(dp));
per(i, , n_+) {
mx = ;
rep(j, b[i], maxm)
mx = max(mx, dp[j]);
suf[i] = ++mx;
dp[b[i]] = mx;
} // iteration
int tmp, n2 = n+n; rep(i, , n+) {
rep(j, , n+) {
if (a[j] < a[i])
continue;
tmp = pre[i+n_-n] + suf[j] + c[a[i]]*(t-n2);
ans = max(ans, tmp);
}
} printf("%d\n", ans); #ifndef ONLINE_JUDGE
printf("time = %d.\n", (int)clock());
#endif return ;
}