题意:
给定长度为n的序列a,
现在要求给每个a[]加上正负号
问有多少种连续子段的和为0,答案对1e9+7取模
数据范围:n<=1000,sum(a[i])<=1e4
解法:
背包问题变形,考虑+-a[i]接在前面的段之后,以及a[i]单独作为子段开头即可
另外值域到了负数,加个base就行了
code:
#include<bits/stdc++.h>
using namespace std;
const int maxm=1e4+5;
const int mod=1e9+7;
const int base=10000;
int d[1005][maxm*2];
int a[maxm];
int n;
signed main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
int ans=0;
for(int i=1;i<=n;i++){
for(int j=-base+a[i];j<=base-a[i];j++){//考虑+-a[i]接在后面
d[i][j+base]=(d[i-1][j-a[i]+base]+d[i-1][j+a[i]+base])%mod;
}
d[i][a[i]+base]++;//考虑+-a[i]作为开头
d[i][-a[i]+base]++;
ans=(ans+d[i][base])%mod;
}
printf("%d\n",ans);
return 0;
}