wap手机网站建设,广州建设技术职业学院官网,网站建设文案策划,网上销售平台题意#xff1a;
给定长度为n的数列,要求每个数都在的范围#xff0c;且任意长度大于等于2的区间和都大于等于0#xff0c;问方案数。。
思路#xff1a;
首先要看出是dp题#xff0c;用来表示遍历到第i位且后缀和最小为x的可行方案数#xff08;此时的后缀可以只有最…题意
给定长度为n的数列,要求每个数都在的范围且任意长度大于等于2的区间和都大于等于0问方案数。。
思路
首先要看出是dp题用来表示遍历到第i位且后缀和最小为x的可行方案数此时的后缀可以只有最后一位。很显然j的值在区间。下面考虑dp如何转换 1.对于。 先讨论可由加一位值为 转换而来也可由加一位值为0 转换而来。就有。再讨论可由加一位值为 转换而来也可由 加一位值为1转换而来。就有。依次讨论可以得出可以由,末位加值为转换而来也可由末位加x转换而来。综上所诉 2.对于。可以去验证只有,末位加值为x才能转换成。所以。
为了方便计算我们把这个区间平移映射到区间上。按照上述思想去找新的dp转换式就有 由于都是求和到2m所以可以考虑后缀和优化。
代码
//#define _CRT_SECURE_NO_WARNINGS
//#includeiostream
//#includealgorithm
//#includecstdio
//#includemap
//#includestring.h
//#includestring
//#includevector
//#include__msvc_all_public_headers.hpp
#includebits/stdc.h
using namespace std;
#define ll long long
const ll mod 998244353;
const int N 5005;
ll dp[N][N*2];//dp[i][j]表示遍历到i位后缀和最小为j且合法的数量。这里后缀和包含了只含有最后一位的情况
ll sum[N * 2];//后缀数组
int main()
{ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);int n, m;cin n m;ll ans 0;//初始化for (int i 0; i m*2; i){dp[1][i] 1;}for (int i 2; i n; i){//处理后缀和for (int j m * 2; j 0; j--)sum[j] (sum[j 1] dp[i - 1][j]) % mod;//[0,m的情况for (int j 0; j m; j){dp[i][j] sum[2 * m - j];}//[m,2m]的情况for (int j m; j 2 * m; j){dp[i][j] sum[j - m];}}//统计for (int i 0; i m * 2; i){ans (ans dp[n][i]) % mod;}cout ans endl;return 0;
}