#include <bits/stdc++.h>
using namespace std;
#define endl "\n"
#define debug cout<<"debug"<<endl
mt19937 rd(time(0));
typedef long long ll;
typedef long double ld;
typedef pair<int, int> PII;
const double eps = 1e-8;
const double PI = 3.14159265358979323;
const int N = 2e5+10, M = 2*N, mod = 998244353;
const int INF = 0x3f3f3f3f;
int n;
int a[N];
int dp[310][300*300*2+10];
int D = 300*300;
// 因为n<=300, 所以可知值域为[-300*300, 300*300], 那么可以根据值来进行转移
// dp[i][j] 表示第i个数变成j的方案数, 那么状态转移方程就很简单了
// dp[i+1][a[i+1]-j] += dp[i][j], dp[i+1][a[i+1]+j] += dp[i][j]
// 因为可能出现负值下标, 所以要加一个偏移量, 使下标为正
// 注意: 若j = 0, 那么对答案的贡献只有一次, 即dp[i+1][a[i+1]-j] += dp[i][j]
void solve()
{
cin>>n;
for(int i = 1; i<=n; i++) cin>>a[i];
dp[2][a[2]+D] = 1;
for(int i = 2; i<n; i++)
{
for(int j = -(D-300); j<=D-300; j++)
{
dp[i + 1][a[i + 1] - j + D] = (dp[i + 1][a[i + 1] - j + D] + dp[i][j + D]) % mod;
dp[i + 1][a[i + 1] + j + D] = (dp[i + 1][a[i + 1] + j + D] + dp[i][j + D]) % mod;
if(!j) dp[i + 1][a[i + 1] + j + D] = ((dp[i + 1][a[i + 1] + j + D] - dp[i][j + D]) % mod +mod) % mod;
}
}
int res = 0;
for(int i = -D; i<=D; i++)
res = (res + dp[n][i+D]) % mod;
cout<<res<<endl;
}
int main()
{
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int T;
T = 1;
// cin>>T;
while(T -- )
{
solve();
}
return 0;
}
cf1783 D. Different Arrays(dp)
最新推荐文章于 2024-07-20 09:51:47 发布