希哥哥推荐的好题。
当k小于100,直接构造出来,然后直接求数组;当k大于100时,构造出 n 个原串,求其最长上升子序列,然后加上(k-n)*原串中出现次数最多的数的出现次数,即为答案。
再推荐一篇博客:https://blog.csdn.net/yjt9299/article/details/82966703
#include<bits/stdc++.h>
#define mem(a,b) memset((a),b,sizeof(a))
typedef long long ll;
const int N=100010;
using namespace std;
int a[10010],b[110],dp[10010];
int main()
{
mem(a,0);
mem(b,0);
mem(dp,0);
int n,k;
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=n;i++)
{
b[i]=0;
for(int j=1;j<=n;j++)
if(a[i]==a[j])
b[i]++;
}
int maxx=0;
for(int i=1;i<=n;i++)
maxx=max(maxx,b[i]);
int cnt;
if(k<=100)
{
cnt=n+1;
for(int i=2;i<=k;i++)
{
for(int j=1;j<=n;j++)
a[cnt++]=a[j];
//开始写错了,写成这样:a[cnt++]=a[(cnt-1)%n];
}
int ans=0;
for(int i=1;i<=n*k;i++)
{
dp[i]=1;
for(int j=1;j<i;j++)
{
if(a[i]>=a[j])
dp[i]=max(dp[i],dp[j]+1);
}
ans=max(ans,dp[i]);
}
printf("%d",ans);
return 0;
}
cnt=n+1;
for(int i=2;i<=n;i++)
for(int j=1;j<=n;j++)
a[cnt++]=a[j];
ll ans=0;
for(int i=1;i<=n*n;i++)
{
dp[i]=1;
for(int j=1;j<i;j++)
{
if(a[i]>=a[j])
dp[i]=max(dp[i],dp[j]+1);
}
ans=max(ans,(ll)dp[i]);
}
ans+=(k-n)*maxx;
printf("%I64d",ans);
return 0;
}