Codeforces 583D. Once Again... (LIS变形)

题目链接:http://codeforces.com/contest/583/problem/D

给你t个长度为n的数组。问你最长不下降子序列的长度。

一开始用第一个n数组的lis和最后一个n数组的lis和中间最多相同的数字出现的个数相加。这是错的,比如5 6 3 4 1 2 

可以发现数组的长度很小,有一个循环节,最多是n吧。所以t <= n只要暴力求解。大于的话,再加上数字出现的最大次数*(t-n)

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 int a[10005], cnt[305], dp[10005], inf = 1e8;
 4 int main()
 5 {
 6     int n, t;
 7     scanf("%d %d", &n, &t);
 8     int max_num = 0, len = n * min(n, t);
 9     for(int i = 1; i <= n; ++i) {
10         scanf("%d", a + i);
11         max_num = max(max_num, ++cnt[a[i]]);
12     }
13     for(int i = n + 1; i <= len; ++i) {
14         a[i] = a[i - n];
15     }
16     int ans = 0;
17     for(int i = 1; i <= len; ++i) {
18         dp[i] = 1;
19         for(int j = i - 1; j >= max(i - n, 1); --j) {  //不需要len*len , i - n之前的dp不是最优的
20             if(a[i] >= a[j]) {
21                 dp[i] = max(dp[i], dp[j] + 1);
22             }
23         }
24         ans = max(ans, dp[i]);
25     }
26     if(t <= n) {
27         printf("%d
", ans);
28     } else {
29         printf("%d
", ans + max_num*(t - n));
30     }
31     return 0;
32 }
原文地址:https://www.cnblogs.com/Recoder/p/5916829.html