Hanghang
2024-11-19 18:35:35
挺好的题,感谢大神 hyc 的指导。
鲜花:场上运气好通过了 D 没过 C,上了大分。
考虑直接模拟
那么自然想到设状态
现在考虑从
定义集合
对于第一种情况,那么我们需要让
第二种情况,需要让
那么本题复杂度就是
可以配合代码理解:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=5003,H=998244353;
ll n,a[N],cnt[N],f[N],g[N],h[N];
bool ban[N];
int main()
{
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=n;i++)if(a[i]!=-1)ban[a[i]]=1;
for(int i=1;i<=n;i++)cnt[i]=cnt[i-1]+(ban[i]==0),f[i]=1;
for(int t=1,w=0;t<n;w+=a[t++]==-1)
{
memcpy(g,f,sizeof(g));memset(f,0,sizeof(f));
for(int i=1;i<=n;i++)h[i]=(h[i-1]+(ban[i]==0)*g[i])%H;
for(int i=1;i<=n;i++)
{
if(a[t]==-1)f[i]=(g[i]*(cnt[i-1]-w)+h[i-1])%H;
else if(i>a[t])f[i]=(g[i]+g[a[t]])%H;
}
}
cout<<f[n];
}