【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
", 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
", ans);
134     
135     #ifndef ONLINE_JUDGE
136         printf("time = %d.
", (int)clock());
137     #endif
138     
139     return 0;
140 }
原文地址:https://www.cnblogs.com/bombe1013/p/4863850.html