zoukankan      html  css  js  c++  java
  • POJ 3342 树形DP+Hash

    这是很久很久以前做的一道题,可惜当时WA了一页以后放弃了。
    今天我又重新捡了起来。(哈哈1A了)
    题意:
    没有上司的舞会+判重

    思路:
    hash一下+树形DP
    题目中给的人名hash到数字,再进行运算。
    树形DP
    f[x][0]+=max(f[x.son][0],f[x.son][1]);
    f[x][1]+=f[x.son][0];
    f[x][0]表示不选这个节点,f[x][1]表示选这个节点。
    如果选了这个节点,那么它的儿子必定不选。
    如果不选这个节点,它的儿子们可选可不选 取最大的即可。

    然后就是坑爹的判重。

    怎么判重呢?
    如果n为2的话 肯定是No不用解释了吧

    然后就从1到n遍历一遍 如果选这个节点和不选这个节点的人数是一样的就遍历它的儿子 如果有任何一个儿子节点选这个儿子节点和不选这个儿子节点的人数是一样的话 那么就是No
    否则就是Yes

    // by SiriusRen
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    int n,tot,num,first[205],v[666],next[666],Hash[1000008],jya,jyb,f[666][2];
    char a[105],b[105];
    void add(int x,int y){v[tot]=y,next[tot]=first[x],first[x]=tot++;}
    void dfs(int x){
        f[x][1]=1;
        for(int i=first[x];~i;i=next[i]){
            dfs(v[i]);
            f[x][0]+=max(f[v[i]][0],f[v[i]][1]);
            f[x][1]+=f[v[i]][0];
        }
    }
    int main(){
        st:while(scanf("%d",&n)&&n){
            scanf("%s",a);
            jya=tot=0;num=1;memset(first,-1,sizeof(first));
            memset(f,0,sizeof(f)),memset(Hash,0,sizeof(Hash));
            int len=strlen(a);
            for(int i=0;i<len;i++)jya=(jya*256+a[i])%1000007;
            Hash[jya]=1;
            for(int i=1;i<n;i++){
                scanf("%s%s",a,b);
                int lena=strlen(a),lenb=strlen(b);jya=jyb=0;
                for(int i=0;i<lena;i++)jya=(jya*256+a[i])%1000007;
                if(!Hash[jya])Hash[jya]=++num;
                for(int i=0;i<lenb;i++)jyb=(jyb*256+b[i])%1000007;
                if(!Hash[jyb])Hash[jyb]=++num;
                add(Hash[jyb],Hash[jya]);
            }
            if(n==2){puts("1 No");goto st;}
            dfs(1);
            printf("%d ",max(f[1][0],f[1][1]));
            for(int i=1;i<=n;i++)
                if(f[i][0]==f[i][1])
                    for(int j=first[i];~j;j=next[j])
                        if(f[v[j]][0]==f[v[j]][1]){puts("No");goto st;}
            puts("Yes");
        }
    }

    这里写图片描述

  • 相关阅读:
    【LeetCode】46. 全排列(回溯)
    [P2894][USACO08FEB] 酒店Hotel (线段树+懒标记下传)
    [P2680][NOIP2015T6] 运输计划 (LCA+树上差分+二分)
    静态主席树学习笔记
    [P1941][NOIP2014T3] 飞扬的小鸟 (0/1背包+完全背包)
    [P1084][NOIP2012T6] 疫情控制 (二分+贪心+LCA)
    [P3959][NOIP2017T5] 宝藏 (状压DP+DFS)
    [P2679][NOIP2015T5] 子串 (DP+滚动数组)
    [P1314][NOIP2011T5] 聪明的质检员 (二分+前缀和)
    [P1966][NOIP2013T2] 火柴排队 (求逆序对+归并排序/树状数组)
  • 原文地址:https://www.cnblogs.com/SiriusRen/p/6532347.html
Copyright © 2011-2022 走看看