神奇数据
查看原帖
神奇数据
848391
fantastic_dream楼主2023/8/10 09:43

O(Tvn)O(Tvn) 做法,极端情况下运算量是 101110^{11} 级别的也能赛时 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;
}
2023/8/10 09:43
加载中...