题意:
给出一个数字串,问任取子串,见子串的每个数字之前加上‘+’或者‘-’使得这个子串的和为0,那么这样的子串个数有多少。
题解:
明显是dp,数据量也不是很大,题目所给了总数的和不会超过10000这其实就是一个状态,dp是统计一类问题的足有解,然后找出我们想要的问题解,那么这题就是统计前i数字和为num的种类数,计算完后只要得到和为0的个数就好。那么状态方程很容易了dp[i][j]表示到i位置,和为j的子串个数。
#include<iostream>
#include<math.h>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<vector>
#include<map>
using namespace std;
typedef long long lld;
const int oo=0x3f3f3f3f;
const lld OO=1LL<<61;
const int MOD=1000000007;
lld dp[1005][20005];
int a[1005];
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
memset(dp,0,sizeof dp);
for(int i=0;i<=n;i++)
dp[i][10000]=1;
for(int i=1;i<=n;i++)
{
for(int j=0;j<=20000;j++)
{
if(j+a[i]<=20000)
dp[i][j+a[i]]=(dp[i][j+a[i]]+dp[i-1][j]+MOD)%MOD;
if(j-a[i]>=0)
dp[i][j-a[i]]=(dp[i][j-a[i]]+dp[i-1][j]+MOD)%MOD;
}
}
lld ans=0;
for(int i=1;i<=n;i++)
ans=(ans+dp[i][10000]-1+MOD)%MOD;
cout<<ans<<endl;
}
return 0;
}
/**
*/