2 条题解

  • 0
    @ 2025-10-6 0:59:36

    楼下 lzdlzd 写的是不是太笼统了

    我把怎么背包的展开讲讲?

    首先我们发现有个中位数,然后我们就可以很套路得考虑二分,就是如果大于等于这个中位数,我们就设为1,反之为0

    然后如果某一个值可以成为答案,当且仅当我把 nval+1n-val+1 个1放进去以后至少有 kk 个合法的花。

    然后我们发现这个二分非常弱智,因为我们不需要这个唐氏的二分。

    我们可以直接树上 DPDP 来跑我往里面丢若干个1,最多让多少朵花合法。

    然后我们发现我们的1肯定是从根开始连续的一段子树。

    然后就是经典的背包问题了。

    感觉思路很好想,但是可能因为我太菜了,调了好久

    我个人认为这道题有下位紫了

    然后强烈谴责出题人,因为我的代码可以跑满 n2n^2 的,但是最大的点 11ms11ms 说明出题人根本没有构造极限数据。

    我预计里面最大的 nn 不超过1000

    #include<bits/stdc++.h>
    #define int short
    #define N 10001
    using namespace std;
    int f[N][N],siz[N];
    vector<int>G[N];
    int res[N];
    int route[N];
    int dept;
    void dfs(int x,int fa){
    //	g[x][dep[x]]=1;
    //	mxdep[x]=dep[x];
    	route[++dept]=x;
    	++f[route[(dept+1)/2]][1];
    	for(int i=0; i<G[x].size(); i++){
    		int y=G[x][i];
    		if(y==fa)continue;
    		dfs(y,x);
    //		mxdep[x]=max(mxdep[x],mxdep[y]);
    //		for(int j=dep[y]; j<=mxdep[y]; j++)g[x][j]+=g[y][j];
    	}dept--;
    	
    }int n;
    void dfs2(int x,int fa){
    	siz[x]=1;
    	f[x][0]=0;
    	for(int i=0; i<G[x].size(); i++){
    		int y=G[x][i];
    		if(y==fa)continue;
    		dfs2(y,x);
    		for(int j=siz[x]; j>=1; j--){
    			for(int k=0; k<=siz[y]; k++){
    				f[x][j+k]=max(f[x][j+k],(short)(f[y][k]+f[x][j]));
    			}
    		}siz[x]+=siz[y];
    	}
    	if(x==1){
    		for(int j=1; j<=siz[x]; j++){
    //			cout<<f[x][j]<<" ";
    			res[f[x][j]]=max(res[f[x][j]],(short)(n-j+1));
    		}
    //		cout<<endl;
    	}
    	
    }
    signed main(){
    	freopen("blossom.in","r",stdin);
    	freopen("blossom.out","w",stdout);
    	int T;scanf("%d",&T);
    	while(T--){
    		scanf("%d",&n);
    		for(int i=1; i<=n; i++)G[i].clear(),res[i]=0;
    		for(int i=1; i<=n; i++){
    			for(int j=1; j<=n; j++){
    				f[i][j]=0;
    			}
    		}
    		for(int i=1; i<n; i++){
    			int x,y;scanf("%d%d",&x,&y);
    			G[x].push_back(y),G[y].push_back(x);
    		}
    		dfs(1,1);
    		dfs2(1,1);
    		res[n+1]=0;
    		for(int i=n; i>=1; i--)res[i]=max(res[i],res[i+1]);
    		for(int i=1; i<=n; i++)printf("%d ",res[i]);
    		printf("\n");
    	}
    	return 0;
    }
    
    

    信息

    ID
    450
    时间
    1000ms
    内存
    256MiB
    难度
    9
    标签
    (无)
    递交数
    14
    已通过
    3
    上传者