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)

 #include <bits/stdc++.h>
using namespace std;
int a[], cnt[], dp[], inf = 1e8;
int main()
{
int n, t;
scanf("%d %d", &n, &t);
int max_num = , len = n * min(n, t);
for(int i = ; i <= n; ++i) {
scanf("%d", a + i);
max_num = max(max_num, ++cnt[a[i]]);
}
for(int i = n + ; i <= len; ++i) {
a[i] = a[i - n];
}
int ans = ;
for(int i = ; i <= len; ++i) {
dp[i] = ;
for(int j = i - ; j >= max(i - n, ); --j) { //不需要len*len , i - n之前的dp不是最优的
if(a[i] >= a[j]) {
dp[i] = max(dp[i], dp[j] + );
}
}
ans = max(ans, dp[i]);
}
if(t <= n) {
printf("%d\n", ans);
} else {
printf("%d\n", ans + max_num*(t - n));
}
return ;
}
上一篇:微软职位内部推荐-Sr DEV Lead, Bing Search Relevance


下一篇:通过批处理(bat)命令创建mysql数据库及用户等