O(Tvn) 做法,极端情况下运算量是 1011 级别的也能赛时 AC 神奇(但是我比赛时边界调了好久 qwq)
#include<bits/stdc++.h>
using namespace std;
int t,n,sz[1005],f[5000005],b[5000005];
bool yj,be[1005];
int main(){
cin>>t;
while(t--){
memset(f,0,sizeof(f)),memset(b,0,sizeof(b)),memset(be,0,sizeof(be));
yj=0;
int sum=0,pj,pos=0,zs=0,ys=0;
cin>>n;
for(int i=1;i<=n;i++){
cin>>sz[i];
sum+=sz[i];
}
pj=sum/n;
if(pj*n==sum){
sort(sz+1,sz+n+1);
for(int i=1;i<=n;i++){
if(sz[i-1]!=sz[i]) be[i]=1;
if(sz[i]==pj){
yj=1;
cout<<"Yes"<<'\n';
break;
}
if(!pos) zs+=(pj-sz[i]);
else ys+=(sz[i]-pj);
if(sz[i]<pj&&sz[i+1]>pj&&!pos) pos=i;
}
if(!yj){
for(int i=1;i<=pos;i++){
f[pj-sz[i]]=1;
for(int j=zs;j>=1;j--){
if(j==pj-sz[i]&&be[i]) continue;
if(f[j]&&f[j+pj-sz[i]]) f[j+pj-sz[i]]=min(f[j]+1,f[j+pj-sz[i]]);
else if(f[j]) f[j+pj-sz[i]]=f[j]+1;
}
}
for(int i=pos+1;i<=n;i++){
b[sz[i]-pj]=1;
for(int j=ys;j>=1;j--){
if(j==sz[i]-pj&&be[i]) continue;
if(b[j]&&b[j+sz[i]-pj]) b[j+sz[i]-pj]=min(b[j+sz[i]-pj],b[j]+1);
else if(b[j]) b[j+sz[i]-pj]=b[j]+1;
}
}
for(int i=1;i<=min(zs,ys);i++){
if(f[i]+b[i]<n&&f[i]>0&&b[i]>0){
yj=1;
cout<<"Yes"<<'\n';
break;
}
}
}
}
if(!yj) cout<<"No"<<'\n';
}
return 0;
}