codeforces 383D Antimatter (dp)

题意:

给出一个数字串,问任取子串,见子串的每个数字之前加上‘+’或者‘-’使得这个子串的和为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;
}
/**

*/








你可能感兴趣的:(codeforces 383D Antimatter (dp))