cf582B&&51nod 1566 重复的最长不下子序列

题意

给出一个长度为n的循环节,问有t个这样循环节的数列的最长不下降子序列

题解

若要让一个循环节的所有元素都出现则最多要n个循环节,若有相同的应该更少,因为n不大,直接构造长度为 n×n 的数列做最长不下降子序列.若剩下还有没用上的,一定是选择出现次数最多的元素插在 n×n 的数列中,不到n节的话直接做肯定是不会错的…

貌似还有矩阵加速的方法,不太会

#include<cstdio>
#include<algorithm>
using namespace std;

int n,t,ans,len,mx,a[105*105],b[105*105],num[305];

int main(){
    scanf("%d%d",&n,&t);
    for(int i=1;i<=n;++i){
    scanf("%d",&a[i]);
    ++num[a[i]];
    mx=max(mx,num[a[i]]);
    }
    if(t>n) ans=mx*(t-n),t=n;
    for(int i=n+1;i<=t*n;++i)
    a[i]=a[i%n==0?n:i%n];
    for(int i=1;i<=t*n;++i){
    if(a[i]>=b[len]) b[++len]=a[i];
    else{
        int pos=upper_bound(b+1,b+len+1,a[i])-b;
        b[pos]=a[i];
    }
    }
    printf("%d\n",ans+len);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值