zoukankan      html  css  js  c++  java
  • P5566 [SDOI2008]红黑树 贪心|动态规划

    题意:

    求一颗(n)个节点的红黑树红色节点数目最多和最少

    红黑树是满足如下性质的的染色二叉搜索树:

    1. 每个结点被染成红色或黑色;
    2. 每个前端结点为黑色结点;
    3. 任一红结点的子结点均为黑结点;
    4. 在从任一结点到其子孙前端结点的所有路径上具有相同的黑结点数。
    5. 二叉搜索树结点中的空指针看作是指向一个空结点,则称这类空结点为二叉搜索树的前端结点。并规定所有前端结点的高度为 -1。

    范围&性质:(1le nle 5000)

    分析:

    • 贪心

    首先对于一颗(n)个点的红黑树,他必定存在且仅存在(n+1)个前端节点,我们构造红黑树的过程可以看做,用这(n+1)个前端节点反向递推到根节点的过程

    由于前端节点的颜色全是黑色,所以我们考虑一堆黑色的叶子结点向上递推的过程,由上面的性质3,4我们可以推出以下几种情况:

    1. 两个黑点变成一个黑点
    2. 三个黑点变成一个红点一个黑点
    3. 四个黑点变成一个黑点和两个红点
    4. 五个黑点变成两个黑点一个红点

    这里有一张图,其中最下面一层黑色节点可以看做是前端节点(来源网上,侵删)

    img

    对于红色节点最少的情况我们按照两个黑点一组的情况去反向递推,这样每次操作得到的红色节点最少

    对于红色节点最多的情况我们按照四个黑点一组的情况去合并,这样每次操作得到的红色节点最多

    • 动态规划(以后填坑,下次一定

    代码:

    • 贪心:
    #include<bits/stdc++.h>
    
    using namespace std;
    
    namespace zzc
    {
    	int n,ans,m;
    	
    	void work()
    	{
    		scanf("%d",&n);
    		m=n+1;
    		while(m>1)
    		{
    			ans+=m&1;
    			m>>=1;
    		}
    		printf("%d
    ",ans);
    		m=n+1;ans=0;
    		while(m>1)
    		{
    			if(m==2) ans++,m--;
    			else if((m&3)==1) ans+=((m>>2)<<1)-1,m>>=2,m++;
    			else if((m&3)==2) ans+=((m>>2)<<1),m>>=2,m++;
    			else if((m&3)==3) ans+=((m>>2)<<1)+1,m>>=2,m++;
    			else ans+=(m>>1),m>>=2;
    		 } 
    		 printf("%d
    ",ans);
    	}
    	
    }
    
    int main()
    {
    	zzc::work();
    	return 0;
    }
    
  • 相关阅读:
    MVC中使用AuthorizeAttribute做身份验证操作
    MVC Dynamic Authorization--示例市在Action前进行的验证,应提前到Auth过滤器
    forms
    UEditor
    Test log4net
    log4net.config
    [转]log4net使用(WinForm/WebFrom)
    如何指定模型的显示格式和模板
    64位系统中连接Access数据库文件的一个问题
    VS2008简体中文正式版序列号
  • 原文地址:https://www.cnblogs.com/youth518/p/13699147.html
Copyright © 2011-2022 走看看