BZOJ 4361: isn

本文介绍了一种解决特定计数问题的算法,通过动态规划和离散化处理,求解给定序列中所有可能的不下降子序列的方案数,并考虑到题目要求一旦序列不下降即停止操作的限制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

传送门

见计数想容斥

考虑先求出 $F[i]$ 表示每种长度的不下降子序列的方案数,但是可能有多算,因为这样有算 从长度 $i+1$ 的不下降子序列变成长度为 $i$ 的不下降子序列的情况

而根据题目的要求一旦序列不下降就要停止操作,但是可以发现 $F[i]$ 只要扣掉 $F[i+1]*(i+1)$ 就行了

现在考虑一下怎么求 $F[i]$,看到 $n<=2000$,考虑 $dp$,设 $f[i][j]$ 表示以第 $i$ 个数为结尾,长度为 $j$ 的不降子序列方案数

那么枚举前 $i$ 个数所有小于第 $i$ 个数的值 $A[i]$ 的位置 $k$,$f[i][j]+=f[k][j-1]$

这个转移显然可以优化,把数离散化后,对每个长度 $j$ 开一个权值数状数组维护

求出 $f$ 以后 $F[i]=(\sum_{j=1}^{n}f[j][i]) \cdot (n-i)!$(乘上 $(n-i)!$ 是因为那 $n-i$ 个删掉的数可以按任意顺序删除)

最后 $Ans=\sum_{i=1}^{n}F[i]$

具体看代码

 

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
inline int read()
{
    int x=0,f=1; char ch=getchar();
    while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
    while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
    return x*f;
}
const int N=2007,mo=1e9+7;
int n,B[N],m,fac[N],Ans;
struct dat{
    int v,id;
    inline bool operator < (const dat &tmp) const {
        return v<tmp.v;
    }
}A[N];
int f[N][N],g[N],ans[N];
int t[N][N];
inline int fk(int x) { return x>=mo ? x-mo : x; }
inline void add(int p,int x,int y) { while(x<=m) t[p][x]=fk(t[p][x]+y),x+=x&-x; }
inline int query(int p,int x) { int res=0; while(x) res=fk(res+t[p][x]),x-=x&-x; return res; }
int main()
{
    n=read();
    for(int i=1;i<=n;i++) A[i].v=read(),A[i].id=i;
    sort(A+1,A+n+1);
    for(int i=1;i<=n;i++)
    {
        if(i==1||A[i].v!=A[i-1].v) m++;
        B[A[i].id]=m;//离散化
    }
    fac[0]=1; for(int i=1;i<=n;i++) fac[i]=1ll*fac[i-1]*i%mo;
    for(int i=1;i<=n;i++)
    {
        f[i][1]=1;
        for(int j=2;j<=n;j++) f[i][j]=query(j-1,B[i]);
        for(int j=1;j<=n;j++) add(j,B[i],f[i][j]);
    }
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++) g[j]=fk(g[j]+f[i][j]);
    for(int i=n;i>=1;i--)
    {
        Ans=fk(Ans+ 1ll*g[i]*fac[n-i]%mo );
        if(i!=n) Ans=fk(Ans+mo - 1ll*g[i+1]*fac[n-i-1]%mo*(i+1)%mo );
    }
    printf("%d",Ans);
    return 0;
}

 

转载于:https://www.cnblogs.com/LLTYYC/p/10785094.html

内容概要:本文介绍了奕斯伟科技集团基于RISC-V架构开发的EAM2011芯片及其应用研究。EAM2011是一款高性能实时控制芯片,支持160MHz主频和AI算法,符合汽车电子AEC-Q100 Grade 2和ASIL-B安全标准。文章详细描述了芯片的关键特性、配套软件开发套件(SDK)和集成开发环境(IDE),以及基于该芯片的ESWINEBP3901开发板的硬件资源和接口配置。文中提供了详细的代码示例,涵盖时钟配置、GPIO控制、ADC采样、CAN通信、PWM输出及RTOS任务创建等功能实现。此外,还介绍了硬件申领流程、技术资料获取渠道及开发建议,帮助开发者高效启动基于EAM2011芯片的开发工作。 适合人群:具备嵌入式系统开发经验的研发人员,特别是对RISC-V架构感兴趣的工程师和技术爱好者。 使用场景及目标:①了解EAM2011芯片的特性和应用场景,如智能汽车、智能家居和工业控制;②掌握基于EAM2011芯片的开发板和芯片的硬件资源和接口配置;③学习如何实现基本的外设驱动,如GPIO、ADC、CAN、PWM等;④通过RTOS任务创建示例,理解多任务处理和实时系统的实现。 其他说明:开发者可以根据实际需求扩展这些基础功能。建议优先掌握《EAM2011参考手册》中的关键外设寄存器配置方法,这对底层驱动开发至关重要。同时,注意硬件申领的时效性和替代方案,确保开发工作的顺利进行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值