【广州市选2014】Tree(tree)

本文介绍了一种算法,用于从给定的整数序列中找出隐藏的最大平衡二叉树,平衡二叉树是一种特殊的二叉树,其左右子树叶子节点的权值之和相等。文章详细解释了问题背景及解决方案,并附带了解题思路和伪代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Description

下图展示了一种二叉树:

这里写图片描述

这种二叉树的每个叶子节点上都标注了权值,而且具有以下有趣的特性:每个非叶子节点,其左右子树叶子节点的权值之和相等。我们称这种二叉树叫平衡二叉树。

我们将一棵平衡二叉树叶子节点的权值从左到右列出来,假如这个权值序列是另一个序列A的子序列,我们称这棵平衡二叉树“隐藏”在序列A当中。在本题中,我们称一个序列S2是另一个序列S1的子序列,当且仅当S2可以由S1中删除0个或多个元素,但不改变S1中剩余元素的相对位置获得。

例如,上图中的平衡二叉树隐藏在序列3 4 1 3 1 2 4 4 6中,因为4 1 1 2 4 4是该序列的子序列。

你的任务是对给定的整数序列,寻找当中隐藏的具有最多叶子节点的平衡二叉树。

Input

输入的第一行是一个正整数n(n<=1000),分别序列的元素数目,第二行是用空格分隔的n个整数ai(1<=i<=n,1<=ai<=500)代表了该序列的第i个元素。

Output

输出只有一个整数,代表该序列当中隐藏的具有最多叶子节点的平衡二叉树的叶子节点总数。

Sample Input

输入1:

9

3 4 1 3 1 2 4 4 6

输入2:

4

3 12 6 3

输入3:

10

10 9 8 7 6 5 4 3 2 1

输入4:

11

10 9 8 7 6 5 4 3 2 1 1

输入5:

8

1 1 1 1 1 1 1 1

Sample Output

输出1:

6

输出2:

2

输出3:

1

输出4:

5

输出5:

8

Data Constraint

n<=1000,1<=ai<=500

题解

我们设fx表示现在取的值和为x,最多可以取fx个数
可以发现选的数都满足 ai=2xy这样的形式,所以我们可以先枚举y然后找到每次合法的ai
然后fx=max(f[x],f[x-ai]),这条方程式在ai|x的时候可以转移
还要卡一下常数才可以过

贴代码

var
    f:array[0..500005]of longint;
    a:array[0..1005]of longint;
    bz:array[0..1005]of boolean;
    i,j,k,l,n,m,x,y,z,ans,maxx,macc:longint;
    b:boolean;
begin
    assign(input,'tree.in'); reset(input);
    assign(output,'tree.out'); rewrite(output);
    readln(n);
    for i:=1 to n do read(a[i]);
    readln;
    for z:=1 to 500 do
    begin
        maxx:=0;
        macc:=0;
        if b then fillchar(f,sizeof(f),0);
        b:=false;
        for i:=1 to n do
        if (bz[i]=false) and (a[i] mod z=0) and ((a[i] div z)=(a[i] div z) and -(a[i] div z)) then
        begin
            b:=true;
            //x:=a[i] div z;
            //if (bz[i]=true) or (a[i] mod z<>0) or (x<>x and -x) then continue;
            for j:=maxx downto 0 do
            if j mod a[i]=0 then break;
            while j>=0 do
            begin
                if (j<>0) and (f[j]=0) then
                begin
                    j:=j-a[i];
                    continue;
                end;
                x:=j+a[i];
                if f[x]<f[j]+1 then f[x]:=f[j]+1;
                if x>macc then macc:=x;
                x:=x div z;
                if (x=x and -x) and (f[j+a[i]]>ans) then ans:=f[j+a[i]];
                j:=j-a[i];
            end;
            maxx:=macc;
            bz[i]:=true;
        end;
    end;
    writeln(ans);
    close(input); close(output);
end.
import tkinter as tk from tkinter import ttk, messagebox import json import os from datetime import datetime class PersonnelManagementSystem: def __init__(self, root): self.root = root self.root.title("人员信息管理系统") self.root.geometry("900x600") self.root.minsize(800, 500) # 设置中文字体 self.style = ttk.Style() self.style.configure(".", font=("SimHei", 10)) # 数据文件和存储 self.data_file = "personnel_data.json" self.personnel_data = self._load_data() # 创建UI self._create_ui() self._refresh_treeview() def _load_data(self): """加载或初始化数据""" try: if os.path.exists(self.data_file): with open(self.data_file, "r", encoding="utf-8") as f: return json.load(f) else: initial_data = self._create_initial_data() self._save_data(initial_data) return initial_data except Exception as e: messagebox.showerror("错误", f"加载数据失败: {e}") return [] def _save_data(self, data=None): """保存数据到文件""" try: with open(self.data_file, "w", encoding="utf-8") as f: json.dump(data or self.personnel_data, f, ensure_ascii=False, indent=2) except Exception as e: messagebox.showerror("错误", f"保存数据失败: {e}") def _create_initial_data(self): """创建初始示例数据""" now = datetime.now().strftime("%Y-%m-%d %H:%M:%S") return [ {"id": 1, "name": "张三", "gender": "男", "age": 30, "phone": "13800138000", "email": "zhangsan@example.com", "address": "北京市朝阳区", "create_time": now, "update_time": now}, {"id": 2, "name": "李四", "gender": "女", "age": 25, "phone": "13900139000", "email": "lisi@example.com", "address": "上海市浦东新区", "create_time": now, "update_time": now}, {"id": 3, "name": "王五", "gender": "男", "age": 35, "phone": "13700137000", "email": "wangwu@example.com", "address": "广州市天河区", "create_time": now, "update_time": now} ] def _create_ui(self): """创建用户界面""" # 主框架 main_frame = ttk.Frame(self.root, padding=10) main_frame.pack(fill=tk.BOTH, expand=True) # 搜索区域 search_frame = ttk.Frame(main_frame) search_frame.pack(fill=tk.X, pady=5) ttk.Label(search_frame, text="搜索:").pack(side=tk.LEFT, padx=5) self.search_var = tk.StringVar() ttk.Entry(search_frame, textvariable=self.search_var, width=30).pack(side=tk.LEFT, padx=5) ttk.Button(search_frame, text="搜索", command=self._search_data).pack(side=tk.LEFT, padx=5) ttk.Button(search_frame, text="重置", command=self._refresh_treeview).pack(side=tk.LEFT) # 表格区域 tree_frame = ttk.Frame(main_frame) tree_frame.pack(fill=tk.BOTH, expand=True, pady=5) columns = ("id", "name", "gender", "age", "phone", "email", "address", "create_time", "update_time") self.tree = ttk.Treeview(tree_frame, columns=columns, show="headings", selectmode="browse") # 设置列标题和宽度 for col in columns: self.tree.heading(col, text=col.capitalize()) width = 100 if col != "id" else 50 self.tree.column(col, width=width, anchor=tk.CENTER) # 添加滚动条 scrollbar = ttk.Scrollbar(tree_frame, orient=tk.VERTICAL, command=self.tree.yview) self.tree.configure(yscroll=scrollbar.set) scrollbar.pack(side=tk.RIGHT, fill=tk.Y) self.tree.pack(fill=tk.BOTH, expand=True) # 按钮区域 button_frame = ttk.Frame(main_frame) button_frame.pack(fill=tk.X, pady=5) for text, command in [("添加", self._add_person), ("修改", self._edit_person), ("删除", self._delete_person), ("刷新", self._refresh_treeview)]: ttk.Button(button_frame, text=text, command=command).pack(side=tk.LEFT, padx=5) def _refresh_treeview(self, data=None): """刷新表格数据""" for item in self.tree.get_children(): self.tree.delete(item) for person in (data or self.personnel_data): self.tree.insert("", tk.END, values=[ person["id"], person["name"], person["gender"], person["age"], person["phone"], person["email"], person["address"], person["create_time"], person["update_time"] ]) def _search_data(self): """搜索数据""" keyword = self.search_var.get().strip().lower() if not keyword: self._refresh_treeview() return results = [p for p in self.personnel_data if any(keyword in str(val).lower() for val in p.values())] self._refresh_treeview(results) d的知识点
06-25
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值