标签:code include cin its false || syn not namespace
如果一个数组\([a_1,a_2,a_3,...,a_n]a_1=n-1\)并且\(a1>0\),这个数组就被叫为好数组,如果一个序列能正好分为多个好数组,ta就被叫为好序列,现在给定一个序列,求这个序列有多少好子序列,答案对\(998244353\)取模
设 \(f[i]\) 表示从 i 开始选取,有多少个符合条件的序列
转移时候需要倒着来,从后往前转移
每次枚举本次选取的是哪些元素即可
注意小于等于 0 的那些不能选,要丢掉
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int mod = 998244353;
namespace math_mod
{
int qpow(int p, int q)
{
return (q & 1 ? p : 1) * (q ? qpow(p * p % mod, q / 2) : 1) % mod;
}
int inv(int p)
{
return qpow(p, mod - 2);
}
int fac(int p)
{
if (p == 0)
return 1;
return p * fac(p - 1) % mod;
}
int ncr(int n, int r)
{
if (r < 0 || r > n)
return 0;
return fac(n) * inv(fac(r)) % mod * inv(fac(n - r)) % mod;
}
int c__[5005][5005];
void c_presolve()
{
for (int i = 0; i <= 5000; i++)
{
c__[i][0] = c__[i][i] = 1;
for (int j = 1; j < i; j++)
c__[i][j] = c__[i - 1][j] + c__[i - 1][j - 1], c__[i][j] %= mod;
}
}
int __c(int n, int r)
{
if (r < 0 || r > n)
return 0;
if (n > 5000)
return ncr(n, r);
return c__[n][r];
}
}
using namespace math_mod;
int f[5005], a[5005];
signed main()
{
ios::sync_with_stdio(false);
int n;
cin >> n;
for (int i = 1; i <= n; i++)
cin >> a[i];
c_presolve();
f[n + 1] = 1;
for (int i = n; i >= 1; i--)
{
if (a[i] <= 0)
continue;
for (int j = i + a[i] + 1; j <= n + 1; j++)
{
f[i] += f[j] * __c(j - i - 1, a[i]);
f[i] %= mod;
}
}
int ans = 0;
for (int i = 1; i <= n; i++)
ans += f[i];
cout << ans % mod << endl;
}
[CF1000D] Yet Another Problem On a Subsequence - 组合,dp
标签:code include cin its false || syn not namespace
原文地址:https://www.cnblogs.com/mollnn/p/14482467.html