首页 > 其他分享 >间距数列

间距数列

时间:2022-10-03 23:23:31浏览次数:51  
标签:间距 return 数列 operator const mint leqslant mod

题目

满足以下条件的长为 \(n\) 的整数序列 \(a_1, a_2, \cdots, a_n\) 有多少个?

  • \(1 \leqslant a_i \leqslant m\),\(1 \leqslant i \leqslant n\)
  • \(|a_i-a_{i+1}| \geqslant k\ (1 \leqslant i \leqslant n-1)\)

输出答案除以 \(998244353\) 的余数。

限制:

  • \(2 \leqslant n \leqslant 1000\)
  • \(1 \leqslant m \leqslant 5000\)
  • \(0 \leqslant k \leqslant m-1\)

算法分析

dp[i][j] 表示长为 \(i\) 的结尾等于 \(j\) 的数列个数

转移方程:

\( dp[i][j] = (dp[i-1][1] + \cdots + dp[i-1][j-k]) + (dp[i-1][j+k] + \cdots + dp[i-1][m]) \)

然后用前缀和去优化
s[i][j] 表示长为 \(i\) 且结尾 \(\leqslant j\) 的数列个数

初始值:

\(dp[1][1 \sim m] = 1\)
\(s[1][j] = j\)

还需特判一下 \(k = 0\) 的情况,答案是 \(m^n\)

代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 1; i <= (n); ++i)

using namespace std;
using ll = long long;

const int mod = 998244353;
//const int mod = 1000000007;
struct mint {
    ll x;
    mint(ll x=0):x((x%mod+mod)%mod) {}
    mint operator-() const {
        return mint(-x);
    }
    mint& operator+=(const mint a) {
        if ((x += a.x) >= mod) x -= mod;
        return *this;
    }
    mint& operator-=(const mint a) {
        if ((x += mod-a.x) >= mod) x -= mod;
        return *this;
    }
    mint& operator*=(const mint a) {
        (x *= a.x) %= mod;
        return *this;
    }
    mint operator+(const mint a) const {
        return mint(*this) += a;
    }
    mint operator-(const mint a) const {
        return mint(*this) -= a;
    }
    mint operator*(const mint a) const {
        return mint(*this) *= a;
    }
    mint pow(ll t) const {
        if (!t) return 1;
        mint a = pow(t>>1);
        a *= a;
        if (t&1) a *= *this;
        return a;
    }

    // for prime mod
    mint inv() const {
        return pow(mod-2);
    }
    mint& operator/=(const mint a) {
        return *this *= a.inv();
    }
    mint operator/(const mint a) const {
        return mint(*this) /= a;
    }
};
istream& operator>>(istream& is, mint& a) {
    return is >> a.x;
}
ostream& operator<<(ostream& os, const mint& a) {
    return os << a.x;
}

mint dp[1005][5005];
mint s[1005][5005];

int main() {
    int n, m, k;
    cin >> n >> m >> k;
    
    if (k == 0) {
        cout << mint(m).pow(n) << '\n';
        return 0;
    }
    
    rep(j, m) dp[1][j] = 1;
    rep(j, m) s[1][j] = j;
    for (int i = 2; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            mint now;
            if (j-k >= 0) now += s[i-1][j-k];
            if (j+k-1 <= m) now += s[i-1][m] - s[i-1][j+k-1];
            dp[i][j] = now;
            s[i][j] = s[i][j-1] + now;
        }
    }
    
    mint ans;
    rep(j, m) {
        ans += dp[n][j];
    }
    
    cout << ans << '\n';
    
    return 0;
}

标签:间距,return,数列,operator,const,mint,leqslant,mod
From: https://www.cnblogs.com/Melville/p/16751552.html

相关文章

  • 1214. 波动数列
    https://www.acwing.com/problem/content/1216/定义f[i][j]为考虑前i个d,余数为j的count数需要注意的是,根据理解推得的公式,有多种等效形式我这里为n*x+1*d1+2*d2+3*d3+.......
  • 1106 2019数列——15分
    把2019各个数位上的数字2、0、1、9作为一个数列的前4项,用它们去构造一个无穷数列,其中第n(>4)项是它前4项之和的个位数字。例如第5项为2,因为2+0+1+9=12,个位数是......
  • 数列分块入门
    数列分块入门算是入门了吧写在前面本人十分之Naive所以写的不好还请见谅。前置知识暴力线段树线段树貌似也不太需要,但本文建立在你已经会线段树的基础上。但真......
  • LeetCode剑指 Offer II 093 最长斐波那契数列
    LeetCode剑指OfferII093最长斐波那契数列classSolution:deflenLongestFibSubseq(self,arr:List[int])->int:n,loc,ans=len(arr),{},0......
  • js 获取当前地址的查询参数列表
    eg.https://go.gliffy.com/go/html5/launch?_ga=2.201967958.654328489.1658124867-1818406430.1658124867console.log(location.search)结果:?_ga=2.201967958.654328489.16......
  • libnet 函数列表
    libnet提供的接口函数按其作用可分为四类:*内存管理(分配和释放)函数*地址解析函数*数据包构造函数*数据包发送函数以下分别列出这些接口函数及其功能(其参数含义简单易......
  • PADS应用笔记:Layout里对齐和等间距方法
    问题怎么在layout布局时,对元件进对齐和等间距布局呢?方法关于对齐,鼠标选中多个元件后,邮件直接选对齐就好了,根据需求进行中心或者上下左右对齐关于等间距,有两个方法1.......
  • 做题记录整理dp12 P7961 [NOIP2021] 数列(2022/9/26)
    P7961[NOIP2021]数列当时在考场上对于拿部分分这个感念不是很清晰,所以当时连暴力分都没拿。。。事实上这题在看了题解之后还是有很多地方没搞明白,比如最后统计答案,为什......
  • 斐波那契数列(取模)
    题目:菲波那契数列是指这样的数列:数列的第一个和第二个数都为1,接下来每个数都等于前面2个数之和。给出一个正整数a,要求菲波那契数列中第a个数对1000取模的结果是多少。......
  • 斐波那契数列(递归、记忆化搜索、递归)
    题目:菲波那契数列是指这样的数列:数列的第一个和第二个数都为1,接下来每个数都等于前面2个数之和。给出一个正整数k,要求菲波那契数列中第k个数是多少。输入输入一行,......