[CF383D] Antimatter - dp
Description
给定长度为 n 的序列,可以给任意数加上正号或者负号,求有多少种连续子段和为 0 的情况。
Solution
设 (f[i][j]) 表示以第 i 个数结尾的子串,有多少个和为 j
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1005;
const int M = 20005;
const int B = 10002;
const int mod = 1e9 + 7;
int n, f[N][M], a[N], ans;
signed main()
{
ios::sync_with_stdio(false);
cin >> n;
for (int i = 1; i <= n; i++)
cin >> a[i];
for (int i = 1; i <= n; i++)
{
f[i][B + a[i]] = 1;
f[i][B - a[i]] = 1;
for (int j = 0; j < M; j++)
{
if (j + a[i] < M)
(f[i][j] += f[i - 1][j + a[i]]) %= mod;
if (j - a[i] >= 0)
(f[i][j] += f[i - 1][j - a[i]]) %= mod;
}
(ans += f[i][B]) %= mod;
}
cout << ans;
}