可以知道,当T较大时,对于LIS,肯定会有很长的一部分是重复的,而这重复的部分,只能是一个block中出现次数最多的数字组成一序列。所以,对于T》1000时,可以直接求出LIS,剩下T-=1000直接求出现次数最多的数字的个数即可。其实可以不用到1000,只需到n即可。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <vector> using namespace std; const int MAX=105; int p[MAX*MAX*10]; int a[MAX],n,t,m; int dp[MAX*MAX*10]; int bin(int l,int r,int key){ while(l<=r){ int mid=(l+r)>>1; if(dp[mid]>key&&dp[mid-1]<=key) return mid; if(dp[mid]>key) r=mid-1; else l=mid+1; } return 1; } int LIS(int len){ int res=1; dp[res]=p[1]; for(int i=2;i<=len;i++){ if(p[i]>=dp[res]){ dp[++res]=p[i]; } else{ int pos=bin(1,res,p[i]); dp[pos]=p[i]; } } ///cout<<res<<endl; return res; } void slove(int l){ int ans=LIS(l); /// cout<<ans<<endl; sort(a+1,a+1+n); int counts=1,maxlen=1; for(int i=2;i<=n;i++){ if(a[i]==a[i-1]) counts++; else{ if(counts>maxlen) maxlen=counts; counts=1; } } if(counts>maxlen) maxlen=counts; printf("%d ",ans+(t-m)*maxlen); } int main(){ while(scanf("%d%d",&n,&t)!=EOF){ for(int i=1;i<=n;i++){ scanf("%d",&a[i]); } m=min(1000,t); dp[0]=-1e9+7; for(int i=0;i<m;i++){ for(int j=1;j<=n;j++){ p[i*n+j]=a[j]; dp[i*n+j]=1e9+7; } } slove(m*n); } return 0; }