J.Qu'est-ce Que C'est?
题意
问所有仅由 之间的数组成的长度为 整数序列中,任意长度大于等于 的区间的和都大于 的整数序列数量有多少。
解题思路
考虑使用动态规划,设 为前 个数最小后缀和为 的整数序列数量,设整数序列为 ,最小后缀和指对于所有 的 。
- 当 时,第 个位置的最小后缀和为 ,那么我们可以加上所有长度为 的最小后缀和大于等于 的整数序列数量,假如第 个位置的最小后缀和小于 的话第 个位置的最小后缀和是不可能为 的,并且这些情况也包括了第 个位置最小后缀和为 的所有情况,状态转移方程为:。
- 当 时,所有长度为 的最小后缀和为 的整数序列的第 个位置一定是 ,因为假如是后缀长度大于等于 的和为 , 又是小于 的,和题意不符合,所以只能加上长度为 的最小后缀和大于 的整数序列数量。
AC_Code
//
// Created by liuhao.
//
#include<bits/stdc++.h>
using namespace std;
#define ios ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
const int mod=998244353;
signed main()
{
ios;
int n,m;
cin>>n>>m;
vector<vector<int>>dp(n+1,vector<int>(2*m+2,0)),sum(n+1,vector<int>(2*m+2,0));
for(int i=2*m;i>=0;i--)
{
dp[1][i]=1;
sum[1][i]=sum[1][i+1]+1;
}
for(int i=2;i<=n;i++)
{
for (int j = -m; j <= m; j++) {
if(j<0)dp[i][j+m]=sum[i-1][-j+m];
else {
dp[i][j + m] = sum[i - 1][j - m + m];
}
}
for (int j = m; j >=-m ; j--) {
sum[i][j+m]=sum[i][j+1+m]+dp[i][j+m];
sum[i][j+m]%=mod;
}
}
cout<<sum[n][0];
return 0;
}