1. /*
  2. WTF
  3. 写了好久了 开始的时候题目读错了 建图建错了
  4. 搜索写的也不好 感觉会T
  5. 总之 第一次写的很low
  6. 贴一下吧
  7. */
  8. #include<iostream>
  9. #include<cstdio>
  10. #include<cstring>
  11. #define N 40
  12. #define M 40
  13. using namespace std;
  14. int n,g[N*N][N*N],a[][M*M];
  15. int num[],ans,maxx,f[N*N][N*N];
  16. struct node
  17. {
  18. int c[],data;
  19. int x[],y[];
  20. }p[N*N][N*N];
  21. int Get_place(int x,int y)
  22. {
  23. if(x<=n)return ;
  24. if(y>(x-n)*-&&y<=*n)return ;
  25. if(y<=(x-n)*-)return ;
  26. return ;
  27. }
  28. int Dfs(int x,int y)
  29. {
  30. int sum=;
  31. for(int i=;i<=;i++)
  32. for(int j=;j<=;j++)
  33. {
  34. if(p[x][y].c[i]<p[x][y].data&&p[x][y].c[j]>p[x][y].data
  35. &&f[p[x][y].x[i]][p[x][y].y[i]]==&&f[p[x][y].x[j]][p[x][y].y[j]]==)
  36. {
  37. f[p[x][y].x[i]][p[x][y].y[i]]=;f[p[x][y].x[j]][p[x][y].y[j]]=;
  38. sum=max(sum,Dfs(p[x][y].x[i],p[x][y].y[i])+Dfs(p[x][y].x[j],p[x][y].y[j]));
  39. f[p[x][y].x[i]][p[x][y].y[i]]=;f[p[x][y].x[j]][p[x][y].y[j]]=;
  40. }
  41. }
  42. for(int i=;i<=;i++)
  43. {
  44. if(f[p[x][y].x[i]][p[x][y].y[i]]==)
  45. {
  46. f[p[x][y].x[i]][p[x][y].y[i]]=;
  47. sum=max(sum,Dfs(p[x][y].x[i],p[x][y].y[i]));
  48. f[p[x][y].x[i]][p[x][y].y[i]]=;
  49. }
  50. }
  51. return sum;
  52. }
  53. int main()
  54. {
  55. scanf("%d",&n);
  56. for(int k=;k<=;k++)
  57. for(int i=;i<=n*n;i++)
  58. scanf("%d",&a[k][i]);
  59. num[]=n*n;
  60. for(int i=;i<=n*;i++)
  61. for(int j=;j<=*i-;j++)
  62. {
  63. int pi=Get_place(i,j);
  64. if(pi==)g[i][j]=a[pi][num[pi]--];
  65. else g[i][j]=a[pi][++num[pi]];
  66. }
  67. for(int i=;i<=n*;i++)
  68. for(int j=;j<=i*-;j++)
  69. {
  70. if(j&)
  71. {
  72. p[i][j].c[]=g[i][j-];
  73. p[i][j].c[]=g[i][j+];
  74. p[i][j].c[]=g[i+][j+];
  75. p[i][j].data=g[i][j];
  76. p[i][j].x[]=i;p[i][j].y[]=j-;
  77. p[i][j].x[]=i;p[i][j].y[]=j+;
  78. p[i][j].x[]=i+;p[i][j].y[]=j+;
  79. }
  80. else
  81. {
  82. p[i][j].c[]=g[i][j-];
  83. p[i][j].c[]=g[i][j+];
  84. p[i][j].c[]=g[i-][j-];
  85. p[i][j].data=g[i][j];
  86. p[i][j].x[]=i;p[i][j].y[]=j-;
  87. p[i][j].x[]=i;p[i][j].y[]=j+;
  88. p[i][j].x[]=i-;p[i][j].y[]=j-;
  89. }
  90. if(j==)
  91. {
  92. p[i][j].c[]=g[*n+-i][j];
  93. p[i][j].x[]=*n+-i;
  94. p[i][j].y[]=*n-*i+;
  95. }
  96. if(j==i*-)
  97. {
  98. p[i][j].c[]=g[*n+-i][*n-*i+];
  99. p[i][j].x[]=*n+-i;
  100. p[i][j].y[]=*n-*i+;
  101. }
  102. if(i==*n&&(j&))
  103. {
  104. p[i][j].c[]=g[i][*n-j];
  105. p[i][j].x[]=i;
  106. p[i][j].y[]=*n-j;
  107. }
  108. }
  109. //int xi,yi;
  110. //while(~scanf("%d%d",&xi,&yi))
  111. //printf("%d\n%d %d %d\n",p[xi][yi].data,p[xi][yi].c[1],p[xi][yi].c[2],p[xi][yi].c[3]);
  112. for(int i=;i<=n*;i++)
  113. for(int j=;j<=i*-;j++)
  114. {
  115. memset(f,,sizeof(f));
  116. f[i][j]=;ans=max(Dfs(i,j),ans);
  117. }
  118. printf("%d\n",ans);
  119. return ;
  120. }
  1. /*
  2. 换一种建图方式 这样很机智啊 然而我并没有想到
  3. 保留原来的三个4个三角形 然后建图 而不是搞到一个大的三角形里再建图
  4. 具体看代码吧
  5. 我们得到了每个点相邻的三个点的权值以后 需要枚举根 然后扩展结点 统计最大值
  6. 对于每一个点 我们并不需要分开考虑左右都选还是直选左或者直选右
  7. 我们左右都扩展一遍然后取大并做和就ok
  8. 但是介于二叉搜索树的要求 如果我们扩展节点时只要求他和相邻父亲比较大小的话
  9. 不能满足左子树的每个节点都小于根 所以我们扩展的时候再维护一下边界 这样的话就使得树满足性质了
  10. 然而时间复杂度会很大 需要记忆化
  11. 再然而我们这个状态不好表示 只能用3维 f[i][j][k] 表示从j到i 边界是k(不管是左还是右)以i为根的最优解
  12. 再再然而我们又发现这个状态爆空间了-- 降维的话 如果把第三维降掉显然会有重复
  13. 其实我们的j到i是很浪费的 我们可以压缩第二维 把到从j改为从i的第几个相邻的点到的
  14. 这样我们就能存下了 然后就是细节问题了
  15. 开始存小三角形用的5*20*20 n<=18 RE到死....忘记存的三角形不是矩形了.....WTF
  16. */
  17. #include<iostream>
  18. #include<cstdio>
  19. #include<cstring>
  20. #define N 40//数组开大保平安
  21. #define M 20*20*4
  22. using namespace std;
  23. int n,g[][N][N],s[M][],ans;
  24. bool vis[M][M];
  25. int f[M][][M];
  26. void Init()
  27. {
  28. cin>>n;
  29. for(int k=;k<=;k++)
  30. for(int i=;i<=n;i++)
  31. for(int j=;j<=i*-;j++)
  32. cin>>g[k][i][j];
  33. }
  34. void Add(int x,int y)
  35. {
  36. if(vis[x][y]==)
  37. {
  38. vis[x][y]=;
  39. s[x][++s[x][]]=y;
  40. }
  41. if(vis[y][x]==)
  42. {
  43. vis[y][x]=;
  44. s[y][++s[y][]]=x;
  45. }
  46. }
  47. void Build_tree()
  48. {
  49. for(int k=;k<=;k++)//内部点
  50. for(int i=;i<=n-;i++)
  51. for(int j=;j<*i-;j++)
  52. if(j&)
  53. {
  54. Add(g[k][i][j],g[k][i][j+]);
  55. Add(g[k][i][j],g[k][i][j-]);
  56. Add(g[k][i][j],g[k][i+][j+]);
  57. }
  58. else
  59. {
  60. Add(g[k][i][j],g[k][i][j+]);
  61. Add(g[k][i][j],g[k][i][j-]);
  62. Add(g[k][i][j],g[k][i-][j-]);
  63. }
  64. for(int k=;k<=;k++)//底边界偶数点
  65. for(int i=;i<=n*-;i+=)
  66. {
  67. Add(g[k][n][i],g[k][n][i+]);
  68. Add(g[k][n][i],g[k][n][i-]);
  69. Add(g[k][n][i],g[k][n-][i-]);
  70. }
  71. for(int i=;i<=n;i++)//侧边界点
  72. {
  73. Add(g[][i][*i-],g[][i][]);
  74. Add(g[][i][*i-],g[][i][]);
  75. Add(g[][i][*i-],g[][i][]);
  76. }
  77. for(int i=;i<=n*-;i+=)//底边界奇数点
  78. {
  79. Add(g[][n][i],g[][n-(i/)][]);
  80. Add(g[][n][i],g[][i/+][(i/+)*-]);
  81. Add(g[][n][i],g[][n][*n-i]);
  82. }
  83. }
  84. int DP(int i,int l1,int l2)//因为要用到i来自哪 所以左右边界可能颠倒
  85. {
  86. int from=;
  87. while(s[i][from]!=l2)from++;//i是从i的第几个相邻的点连过来的
  88. if(f[i][from][l1]>)return f[i][from][l1];//记忆化
  89. int l,r,lmax=,rmax=;
  90. if(l1>l2)l=l2+,r=l1;//修正左右边界
  91. else l=l1,r=l2-;
  92. for(int j=;j<=;j++)
  93. if(j!=from&&l<=s[i][j]&&r>=s[i][j])
  94. {
  95. if(s[i][j]<i)lmax=max(lmax,DP(s[i][j],l,i));
  96. else rmax=max(rmax,DP(s[i][j],r,i));
  97. }
  98. f[i][from][l1]=lmax+rmax+;
  99. return f[i][from][l1];
  100. }
  101. void Dfs()
  102. {
  103. for(int i=;i<=n*n*;i++)//枚举根节点
  104. {
  105. int lmax=,rmax=;
  106. for(int j=;j<=;j++)
  107. if(s[i][j]<i)lmax=max(lmax,DP(s[i][j],,i));//左子树的所有数在1-i-1之间
  108. else rmax=max(rmax,DP(s[i][j],n*n*,i));//右子树的所有数在i+1-n*n*4之间
  109. ans=max(ans,+lmax+rmax);
  110. }
  111. }
  112. int main()
  113. {
  114. //freopen("bstree.in","r",stdin);
  115. //freopen("bstree.out","w",stdout);
  116. Init();
  117. Build_tree();
  118. Dfs();
  119. cout<<ans<<endl;
  120. return ;
  121. }

codevs 2241 排序二叉树的更多相关文章

  1. 记忆化搜索 codevs 2241 排序二叉树

    codevs 2241 排序二叉树 ★   输入文件:bstree.in   输出文件:bstree.out   简单对比时间限制:1 s   内存限制:128 MB [问题描述] 一个边长为n的正三 ...

  2. C++11 智能指针unique_ptr使用 -- 以排序二叉树为例

    用智能指针可以简化内存管理.以树为例,如果用普通指针,通常是在插入新节点时用new,在析构函数中调用delete:但有了unique_ptr类型的智能指针,就不需要在析构函数中delete了,因为当u ...

  3. 数据结构与算法系列研究五——树、二叉树、三叉树、平衡排序二叉树AVL

    树.二叉树.三叉树.平衡排序二叉树AVL 一.树的定义 树是计算机算法最重要的非线性结构.树中每个数据元素至多有一个直接前驱,但可以有多个直接后继.树是一种以分支关系定义的层次结构.    a.树是n ...

  4. c++(排序二叉树线索化)

    前面我们谈到了排序二叉树,还没有熟悉的同学可以看一下这个,二叉树基本操作.二叉树插入.二叉树删除1.删除2.删除3.但是排序二叉树也不是没有缺点,比如说,如果我们想在排序二叉树中删除一段数据的节点怎么 ...

  5. c++(排序二叉树删除)

    相比较节点的添加,平衡二叉树的删除要复杂一些.因为在删除的过程中,你要考虑到不同的情况,针对每一种不同的情况,你要有针对性的反应和调整.所以在代码编写的过程中,我们可以一边写代码,一边写测试用例.编写 ...

  6. c++(排序二叉树)

    前面我们讲过双向链表的数据结构.每一个循环节点有两个指针,一个指向前面一个节点,一个指向后继节点,这样所有的节点像一颗颗珍珠一样被一根线穿在了一起.然而今天我们讨论的数据结构却有一点不同,它有三个节点 ...

  7. JavaScript实现排序二叉树的相关算法

    1.创建排序二叉树的构造函数 /** * 创建排序二叉树的构造函数 * @param valArr 排序二叉树中节点的值 * @constructor */ function BinaryTree(v ...

  8. Java编程的逻辑 (42) - 排序二叉树

    本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http:/ ...

  9. (原创)像极了爱情的详解排序二叉树,一秒get

    排序二叉树(建立.查找.删除) 二叉树我们已经非常熟悉了,但是除了寻常的储存数据.遍历结构,我们还能用二叉树做什么呢? 我们都知道不同的遍历方式会对相同的树中产生不同的序列结果,排序二叉树就是利用二叉 ...

随机推荐

  1. 如何遍历json属性和动态添加属性

    var person= { name: 'zhangsan', pass: '123' , 'sni.ni' : 'sss', hello:function (){ for(var i=0;i< ...

  2. css3之box-sizing

    css盒子模型中包括几种重要的属性,包括margin.border.padding以及content.但浏览器对其盒子模型的解释则有所不痛,启用标准模式还是IE(怪)模式是与当前页面的文档声明相关的. ...

  3. 8个不可不知的Mac OS X专用命令行工具(转)

    OS X的终端下通用很多Unix的工具和脚本.如果从Linux迁移到OS X会发现很多熟悉的命令和脚本工具,其实并没有任何区别. 但是OS X也提供了很多其他系统所没有的特别的命令行工具.我们推荐8个 ...

  4. underscorejs-some学习

    2.11 some 2.11.1 语法: _.some(list, predicate, [context]) 2.11.2 说明: 对list集合的每个成员根据predicate进行真值检测,如果一 ...

  5. 修改PHP的默认时区

    每个地区都有自己的本地时间,在网上及无线电通信中,时间的转换问题显得格外突出.整个地球分为24个时区,每个时区都有自己的本地时间.在国际无线电或网络通信场合,为了统一起见,使用一个统一的时间,成为通用 ...

  6. UVA - 11346 Probability (概率)

    Description Probability Time Limit: 1 sec  Memory Limit: 16MB Consider rectangular coordinate system ...

  7. Equivalent Strings (字符串相等?)

    Equivalent Strings   E - 暴力求解.DFS Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I ...

  8. Eclipse+Pydev +Django搭建开发环境时容易出错的几点

    1.注意安装的软件和系统的位数是否匹配. 2.安装Django框架的时候注意是否安装了setuptools工具.在Python中,安装第三方模块,是通过setuptools这个工具完成的.Python ...

  9. Java获取程序或项目路径的常用方法

    在写java程序时不可避免要获取文件的路径,比较常用的方法有: 1 在任意的class里调用: this.getClass().getClassLoader().getResource("/ ...

  10. 【HDOJ】2424 Gary's Calculator

    大数乘法加法,直接java A了. import java.util.Scanner; import java.math.BigInteger; public class Main { public ...