AtCoder Beginner Contest 253
E - Distance Sequence
思路:前缀和优化DP
要求$ |a[i]-a[i+1]|>=k\( 定于\)dp[i][j]:\(前\)i\(个数以\)j\(结尾的合法序列数列 \) dp[i][j] += dp[i-1][1~(j-k)]+dp[i-1][(j+k)~m]$
直接写的话复杂度是\(O(nm^2)\)的会TLE,我们发现可以做一个前缀和优化,预处理出上一层的\(dp\)数组的前缀和。
// AC one more times
// nndbk
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 998244353;
ll n,m,k;
ll dp[1100][5100],s[5500];
int main()
{
ios::sync_with_stdio(false); cin.tie(nullptr), cout.tie(nullptr);
cin>>n>>m>>k;
/*
|a[i]-a[i+1]|>=k
dp[i][j]:前i个数以j结尾的合法序列数列
dp[i][j] += dp[i-1][1~(j-k)]+dp[i-1][(j+k)~m]
*/
for(int i = 1;i <= m; i++)
dp[1][i] = 1;
for(int i = 2;i <= n; i++)
{
for(int j = 1;j <= m; j++)
s[j] = (s[j-1]+dp[i-1][j])%mod;
for(int j = 1;j <= m; j++)
{
//这段代码会T
// for(int l = 1;l <= j-k; l++)
// {
// dp[i][j] += dp[i-1][l];
// dp[i][j] %= mod;
// }
// for(int l = j+k;l <= m; l++)
// {
// dp[i][j] += dp[i-1][l];
// dp[i][j] %= mod;
// }
ll l = j-k,r = j+k;
if(k==0)
dp[i][j] += s[m],dp[i][j] %= mod;
else{
if(l>=1)
dp[i][j] += s[l],dp[i][j] %= mod;
if(r<=m)
dp[i][j] = (dp[i][j]+(s[m]-s[r-1])%mod+mod)%mod;
}
}
}
ll ans = 0;
for(int i = 1;i <= m; i++)
ans += dp[n][i],ans %= mod;
cout<<ans<<"\n";
return 0;
}
标签:AtCoder,Beginner,Contest,int,ll,253,dp
From: https://www.cnblogs.com/nannandbk/p/17723251.html