【CF】323 Div2. D. Once Again...
挺有意思的一道题目。
考虑长度为n的数组,重复n次,可以得到n*n的最长上升子序列。同理,也可以得到n*n的最长下降子序列。
因此,把t分成prefix(上升子序列) + cycle(one integer repeating) + sufix(下降子序列)。
当t<=2*n时,暴力解。
注意数据范围。
1 /* 583D */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include <stack> 8 #include <vector> 9 #include <deque> 10 #include <algorithm> 11 #include <cstdio> 12 #include <cmath> 13 #include <ctime> 14 #include <cstring> 15 #include <climits> 16 #include <cctype> 17 #include <cassert> 18 #include <functional> 19 #include <iterator> 20 #include <iomanip> 21 using namespace std; 22 //#pragma comment(linker,"/STACK:102400000,1024000") 23 24 #define sti set<int> 25 #define stpii set<pair<int, int> > 26 #define mpii map<int,int> 27 #define vi vector<int> 28 #define pii pair<int,int> 29 #define vpii vector<pair<int,int> > 30 #define rep(i, a, n) for (int i=a;i<n;++i) 31 #define per(i, a, n) for (int i=n-1;i>=a;--i) 32 #define clr clear 33 #define pb push_back 34 #define mp make_pair 35 #define fir first 36 #define sec second 37 #define all(x) (x).begin(),(x).end() 38 #define SZ(x) ((int)(x).size()) 39 #define lson l, mid, rt<<1 40 #define rson mid+1, r, rt<<1|1 41 42 const int maxn = 105; 43 const int maxm = 305; 44 int c[maxm]; 45 int a[maxn], b[maxn*maxn*2]; 46 int dp[maxm]; 47 int suf[maxn*maxn], pre[maxn*maxn]; 48 49 int main() { 50 ios::sync_with_stdio(false); 51 #ifndef ONLINE_JUDGE 52 freopen("data.in", "r", stdin); 53 freopen("data.out", "w", stdout); 54 #endif 55 56 int n, t; 57 int mx; 58 int ans = 0; 59 60 scanf("%d %d", &n, &t); 61 rep(i, 1, n+1) { 62 scanf("%d", &a[i]); 63 ++c[a[i]]; 64 } 65 66 if (t <= n*2) { 67 rep(i, 1, n+1) { 68 int k = i; 69 rep(j, 1, t+1) { 70 b[k] = a[i]; 71 k += n; 72 } 73 } 74 75 int n_ = n*t; 76 77 memset(dp, 0, sizeof(dp)); 78 rep(i, 1, n_+1) { 79 mx = 0; 80 rep(j, 1, b[i]+1) 81 mx = max(mx, dp[j]); 82 pre[i] = ++mx; 83 dp[b[i]] = mx; 84 } 85 rep(i, 1, n_+1) 86 ans = max(ans, pre[i]); 87 printf("%d\n", ans); 88 return 0; 89 } 90 91 rep(i, 1, n+1) { 92 int k = i; 93 rep(j, 1, n+1) { 94 b[k] = a[i]; 95 k += n; 96 } 97 } 98 99 // calculate prefix 100 int n_ = n*n; 101 102 memset(dp, 0, sizeof(dp)); 103 rep(i, 1, n_+1) { 104 mx = 0; 105 rep(j, 1, b[i]+1) 106 mx = max(mx, dp[j]); 107 pre[i] = ++mx; 108 dp[b[i]] = mx; 109 } 110 111 // calculate suffix 112 memset(dp, 0, sizeof(dp)); 113 per(i, 1, n_+1) { 114 mx = 0; 115 rep(j, b[i], maxm) 116 mx = max(mx, dp[j]); 117 suf[i] = ++mx; 118 dp[b[i]] = mx; 119 } 120 121 // iteration 122 int tmp, n2 = n+n; 123 124 rep(i, 1, n+1) { 125 rep(j, 1, n+1) { 126 if (a[j] < a[i]) 127 continue; 128 tmp = pre[i+n_-n] + suf[j] + c[a[i]]*(t-n2); 129 ans = max(ans, tmp); 130 } 131 } 132 133 printf("%d\n", ans); 134 135 #ifndef ONLINE_JUDGE 136 printf("time = %d.\n", (int)clock()); 137 #endif 138 139 return 0; 140 }