【2019上海网络赛】

≡放荡痞女 提交于 2019-11-29 18:41:50

B题:分成两序列,A>B,A-(a[i]属于A里面的)<=B;

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll mod=1e9+7;
const ll inf=1e18;
ll dp[300*500+5];
int a[300];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,s=0;
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&a[i]),s+=a[i];
sort(a+1,a+1+n);
for(int i=1;i<=s;i++)dp[i]=0;
dp[0]=1;
for(int i=1;i<=n;i++)
for(int j=s;j>=a[i];j--)
(dp[j]+=dp[j-a[i]])%=mod;
ll ans=0;
for(int i=1;i<=n;i++)
{
for(int j=a[i];j<=s;j++)///表示去a[i]后的方案数
dp[j]=(dp[j]-dp[j-a[i]]+mod)%mod;
for(int j=max((s+1)/2-a[i],0);j<=s-j-a[i];j++)///因为我们减掉的a【i】得是任意的,那肯定是最小的也得满足,所以我们上面先排序了后一个一个枚举
ans=(ans+dp[j])%mod;
}
printf("%lld\n",ans);
}
return 0;
}

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!