zoukankan      html  css  js  c++  java
  • hihocoder217周 树形DP

    题目链接
    一棵树,树中包含TRUE、FALSE、AND、OR四种结点,其中TRUE和FALSE是叶子结点,AND和OR结点的儿子包含多个结点,现在要求执行最少次数的以下操作:

    • 把AND变成OR
    • 把OR变成AND

    使得整棵树的bool值结果翻转。

    思路

    只考虑当前结点和它的儿子。
    要想改变当前结点的值,有两种方法:

    • 改变当前结点的操作
    • 改变当前结点的儿子结点的值

    有时甚至需要把这两种方法结合起来,比如:当前结点为AND,它的儿子们全为TRUE。这是要改变当前结点的值,可能要把当前结点改为OR,并且把某个儿子改为FALSE。

    import java.util.ArrayList;
    import java.util.List;
    import java.util.Scanner;
    
    public class Main {
    final int MAX_VLUE = 100000;
    
    class Node {
        List<Node> son = new ArrayList<>();
        String value;
        int parent;
        int reverseValue = -1;
        boolean nowValue = false;
        boolean inited = false;
    
        Node(String value, int parent) {
            this.value = value;
            this.parent = parent;
        }
    
        int reverseOne(boolean toValue) {
            int min = MAX_VLUE;
            for (Node i : son) {
                if (i.getValue() == toValue) return 0;
                min = Math.min(min, i.reverse());
            }
            return min;
        }
    
        int reverseAll(boolean toValue) {
            int s = 0;
            for (Node i : son) {
                if (i.getValue() != toValue) {
                    s += i.reverse();
                }
            }
            return s;
        }
    
    
        //翻转需要的步数
        int reverse() {
            if (reverseValue != -1) return reverseValue;
            if (value.equals("TRUE") || value.equals("FALSE")) return MAX_VLUE;
            if (value.equals("AND")) {
                if (nowValue) {
                    reverseValue = Math.min(reverseOne(false), 1 + reverseAll(false));
                } else {
                    reverseValue = Math.min(reverseAll(true), 1 + reverseOne(true));
                }
            } else if (value.equals("OR")) {
                if (nowValue) {
                    reverseValue = Math.min(1 + reverseOne(false), reverseAll(false));
                } else {
                    reverseValue = Math.min(reverseOne(true), 1 + reverseAll(true));
                }
            }
            return reverseValue;
        }
    
        boolean getValue() {
            if (inited) return nowValue;
            inited = true;
            if (value.equals("TRUE")) {
                nowValue = true;
                return true;
            } else if (value.equals("FALSE")) {
                nowValue = false;
                return false;
            } else if (value.equals("AND")) {
                nowValue = son.stream().allMatch(Node::getValue);
                return nowValue;
            } else if (value.equals("OR")) {
                nowValue = son.stream().anyMatch(Node::getValue);
                return nowValue;
            }
            return false;
        }
    }
    
    Main() {
        Scanner cin = new Scanner(System.in);
        int N = cin.nextInt();
        Node[] a = new Node[N + 1];
        a[0] = new Node("AND", 0);
        for (int i = 1; i <= N; i++) {
            int parent = cin.nextInt();
            String value = cin.next();
            a[i] = new Node(value, parent);
        }
        int root = 1;
        for (int i = 1; i <= N; i++) {
            a[a[i].parent].son.add(a[i]);
            if (a[i].parent == 0) {
                root = i;
            }
        }
        a[root].getValue();
        int step = a[root].reverse();
        if (step >= MAX_VLUE) {
            System.out.println(-1);
        } else {
            System.out.println(step);
        }
    }
    
    public static void main(String[] args) {
        new Main();
    }
    }
    
  • 相关阅读:
    启动控制面板命令大全
    C#下载网页为mht文件
    基于C#语言的可编程表达式计算器设计
    FileSystemWatcher监视文件变动
    C#梁朝伟变刘德华之山寨实现
    Json之语法,格式
    Regex类
    C# 索引器
    优化正则表达式的诀窍
    正则表达式(二) 零宽断言与懒惰匹配以及平衡组
  • 原文地址:https://www.cnblogs.com/weiyinfu/p/9556492.html
Copyright © 2011-2022 走看看