zoukankan      html  css  js  c++  java
  • CF 429C

     
    Iahub and Iahubina went to a picnic in a forest full of trees. Less than 5 minutes passed before Iahub remembered of trees from programming. Moreover, he invented a new problem and Iahubina has to solve it, otherwise Iahub won't give her the food.

    Iahub asks Iahubina: can you build a rooted tree, such that

    • each internal node (a node with at least one son) has at least two sons;
    • node i has ci nodes in its subtree?

    Iahubina has to guess the tree. Being a smart girl, she realized that it's possible no tree can follow Iahub's restrictions. In this way, Iahub will eat all the food. You need to help Iahubina: determine if there's at least one tree following Iahub's restrictions. The required tree must contain n nodes.

    Input

    The first line of the input contains integer n (1 ≤ n ≤ 24). Next line contains n positive integers: the i-th number represents ci(1 ≤ ci ≤ n).

    Output

    Output on the first line "YES" (without quotes) if there exist at least one tree following Iahub's restrictions, otherwise output "NO" (without quotes).

    Sample test(s)
    input
    4
    1 1 1 4
    output
    YES
    input
    5
    1 1 5 2 1
    output
    NO

    中文题意:

    给出一棵树中每个节点子树的大小,要求每个非叶节点至少有2个儿子,问是否能构造出这样一棵树

    解法:

    N<=24,因此可以用状压解。

    首先可以证明如果叶节点<N/2,那么肯定无解

    所以我们可以把非叶节点和叶节点分开处理。

    我们每次其实就是要往一个非叶点里塞点,或者说给每个点找父节点

    我们设状态 f[i][j][k]为已塞完前i个非叶节点,非叶节点是否被塞过(即是否已有父节点的状态为j,还有k个叶节点没有父节点

    然后对于每个点,枚举塞哪些非叶节点即可

    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    
    using namespace std;
    
    bool f[14][8201][14];
    int zt[9011],num[9011];
    int a[101];
    int n,i,j,k,cnt,t;
    
    void Work(int x,int y,int z)
    {
        int lef,i,yf;
        for(i=0;i<(1<<t);i++)if(!(y&i)){
            lef=a[x]-1-zt[i];
            if(lef>=0&&lef<=z){
                if(lef+num[i]>1)f[x][y|i][z-lef]=true;
            }
        }
    }
    
    int main()
    {
        scanf("%d",&n);
        for(i=1;i<=n;i++){
            scanf("%d",&k);
            if(k==1)cnt++;
            else a[++t]=k;
        }
        for(i=1;i<t;i++)
            for(j=i+1;j<=t;j++)if(a[i]<a[j])swap(a[i],a[j]);
        if(n==1&&cnt==1)printf("YES
    ");
        else if(cnt<n/2||cnt==n)printf("NO
    ");
        else{
            for(i=0;i<(1<<t);i++){
                for(j=1;j<=t;j++)if((i&(1<<(j-1)))){
                    zt[i]+=a[j];
                    num[i]++;
                }
            }
            f[0][1][cnt]=true;
            for(i=0;i<t;i++)
                for(j=0;j<(1<<t);j++)
                    for(k=0;k<=cnt;k++)if(f[i][j][k])Work(i+1,j,k);
            if(f[t][(1<<t)-1][0])printf("YES
    ");
            else printf("NO
    ");
        }
    }
  • 相关阅读:
    luffy后台登录+注册+课程
    luffy前台登录+注册+课程
    luffy前台准备
    luffy后台准备
    跨域请求
    pip源和虚拟环境的搭建
    Book接口
    drf-Xadmin的使用
    drf-JWT认证
    drf-自动生成接口文档
  • 原文地址:https://www.cnblogs.com/applejxt/p/4525437.html
Copyright © 2011-2022 走看看