zoukankan      html  css  js  c++  java
  • [CF1000D] Yet Another Problem On a Subsequence

    [CF1000D] Yet Another Problem On a Subsequence - 组合,dp

    Description

    如果一个数组([a_1,a_2,a_3,...,a_n]a_1=n-1)并且(a1>0),这个数组就被叫为好数组,如果一个序列能正好分为多个好数组,ta就被叫为好序列,现在给定一个序列,求这个序列有多少好子序列,答案对(998244353)取模

    Solution

    (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;
    }
    
  • 相关阅读:
    CAP原理、一致性模型、BASE理论和ACID特性
    MyBatis双数据源配置
    MySQL中间件Atlas安装及使用
    MySQL主从切换
    MySQL定时逻辑备份
    MySQL主从搭建
    zabbix监控nginx
    SVN Files 的值“ < < < < < < < .mine”无效。路径中具有非法字符。
    ie8下table的colspan属性与max-with属性的显示错乱问题
    MVC 自定义异常错误页面处理
  • 原文地址:https://www.cnblogs.com/mollnn/p/14482467.html
Copyright © 2011-2022 走看看