这里呢,用的方法是dp,俗话说的好"神用dp,人用暴力",但是呢,我都不会(白嫖大佬的代码)。
方法简介:
首先,先const 一个maxn=666*300+5;这里加5嘛,就只有防爆炸的作用,重要的是这个666*300,为什么要定义一个maxn呢,因为,我们要开一个4*maxn大的二维数组ans[2][maxn*2+5],那么为什么要开一个maxn大的数组呢?
因为,我们需要的一个足够大的数组来储存我们所有可能的结果。那么问题又来了,所有的可能结果包括到什么程度。变看代码,边看注释
#include<bits/stdc++.h>
using namespace std;
const int maxn=666*300+5; //以maxn为分界线,代表小于maxn的为负数的结果,大于maxn为大于0的结果
const int mod=1e8+7;
int cur=1;
int old=0;
int ans[2][maxn*2+5];
int a[maxn];
//取模并赋值。
void mo(int &x,int y)
{
x=(x+y)%mod;
}
int main()
{
int n;
int i,j;
cin>>n;
for(i=0;i<n;++i) cin>>a[i];
ans[cur][maxn]=1; //这里是一切可能的开始,没看懂得先看下面的。
for(i=0;i<n;++i)
{
swap(cur,old); //滚动数组
fill(ans[cur],ans[cur]+maxn*2,0); //初始化当前的所需要更新的数组
for(j=-maxn;j<=maxn;++j)
{
if(j!=-666) mo(ans[cur][maxn+j],ans[old][maxn-j]); //这里表示操作B,便利所有的可能,即便是不需要的可能(比如我们上一次更新当前数组后的a[x]的值为0代表x这个结果在更新后,没有一个可能的值为x)
if(j-a[i]>=-maxn&&j-a[i]!=666) mo(ans[cur][maxn+j],ans[old][maxn+j-a[i]]); //这里是操作A,原理同上
}
}
cout<<ans[cur][maxn-666]<<endl;
return 0;
}