B. Once Again...
Time Limit: 1 Sec
Memory Limit: 256 MB
题目连接
http://codeforces.com/contest/582/problem/BDescription
Input
Output
Print a single number — the length of a sought sequence.
Sample Input
4 3
3 1 4 2
Sample Output
5
HINT
题意
给你一个n*t这么长的序列,然后求最长不递减序列
其中a[i+n]=a[i]
题解:
暴力,如果t<=300,我们就直接暴力求就好了
如果t>的话,我们就大胆猜测,中间肯定是连续选一个数
那么我们就预处理前面以a[i]开始的最长,和后面的以a[i]最长是啥就好了~
代码:
#include<iostream> #include<stdio.h> #include<queue> #include<map> #include<algorithm> #include<string.h> using namespace std; #define maxn 3225020 int a[maxn]; int dp1[maxn]; int dp2[maxn]; int dp3[maxn]; int lis[maxn]; int main() { int n,t;scanf("%d%d",&n,&t); for(int i=1;i<=n;i++) scanf("%d",&a[i]); if(t<=300) { int ans = 0; for(int i=1;i<=n;i++) for(int j=1;j<t;j++) a[j*n+i] = a[i]; for(int i=1;i<=n*t;i++) { lis[i]=1; for(int j=1;j<i;j++) if(a[i]>=a[j]) lis[i]=max(lis[i],lis[j]+1); ans = max(lis[i],ans); } printf("%d\n",ans); return 0; } int k = 200; for(int i=1;i<=n;i++) dp2[a[i]]++; for(int i=1;i<=n;i++) for(int j=1;j<=k;j++) a[j*n+i] = a[i]; for(int i=1;i<=k*n;i++) { lis[i]=1; for(int j=1;j<i;j++) if(a[i]>=a[j]) lis[i]=max(lis[i],lis[j]+1); dp1[a[i]] = max(dp1[a[i]],lis[i]); } memset(lis,0,sizeof(lis)); reverse(a+1,a+1+k*n); for(int i=1;i<=k*n;i++) { lis[i]=1; for(int j=1;j<i;j++) if(a[i]<=a[j]) lis[i]=max(lis[i],lis[j]+1); dp3[a[i]] = max(dp3[a[i]],lis[i]); } int ans = 0; for(int i=0;i<=300;i++) for(int j=i;j<=300;j++) for(int m=j;m<=300;m++) ans = max(dp1[i]+dp2[j]*(t-2*k)+dp3[m],ans); printf("%d\n",ans); }