基本思想:
- 初始状态([0]).
- 小范围表示大范围.
#include<cstdio> #include<iostream> #include<algorithm> #define int long long using namespace std; const int MAXN=8000,INF=2e9,MOD=1e9+7; int a[MAXN],f[MAXN][MAXN],p[MAXN]; signed main(){ int n; cin>>n; p[0]=1; for(int i=1;i<=n;i++){ p[i]=p[i-1]*2; p[i]%=MOD; } int maxx=-INF; for(int i=1;i<=n;i++){ scanf("%d",&a[i]); maxx=max(a[i],maxx); } sort(a+1,a+n+1); int ans=0; f[0][0]=1; for(int i=1;i<=n;i++){ for(int j=0;j<=maxx;j++){ f[i][j]+=f[i-1][j]; f[i][j]=f[i][j]%MOD; if(a[i]<=j+1){ if(a[i]+j<=maxx){ f[i][j+a[i]]+=f[i-1][j]; f[i][j+a[i]]=f[i][j+a[i]]%MOD; } else { ans+=p[n-i]*f[i-1][j]; ans=ans%MOD; } } } } for(int i=1;i<=maxx;i++){ ans+=f[n][i]; ans%=MOD; } cout<<ans<<endl; return 0; }